silvery 0.21.0 → 0.23.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 +1 -1
- package/dist/{Text-Lq0dmj8-.mjs → Text-Ci6UCSTL.mjs} +46 -48
- package/dist/Text-Ci6UCSTL.mjs.map +1 -0
- package/dist/{render-string-DkQacASz.mjs → ag-q9lRlKlt.mjs} +5322 -4259
- package/dist/ag-q9lRlKlt.mjs.map +1 -0
- package/dist/{animation-ZMN2_XKv.mjs → animation-CZ4x2R7C.mjs} +1 -1
- package/dist/{animation-ZMN2_XKv.mjs.map → animation-CZ4x2R7C.mjs.map} +1 -1
- package/dist/{ansi-D1KQMAbf.mjs → ansi-CLmIMnop.mjs} +1 -1
- package/dist/{ansi-D1KQMAbf.mjs.map → ansi-CLmIMnop.mjs.map} +1 -1
- package/dist/{ansi-2Xn0yatP.d.mts → ansi-zmNzgkPB.d.mts} +1 -1
- package/dist/{ansi-2Xn0yatP.d.mts.map → ansi-zmNzgkPB.d.mts.map} +1 -1
- package/dist/{backend-B-WYLUib.mjs → backend-DSiSIc-h.mjs} +2 -2
- package/dist/{backend-B-WYLUib.mjs.map → backend-DSiSIc-h.mjs.map} +1 -1
- package/dist/chain-bridge-CkYcMxlq.mjs +4149 -0
- package/dist/chain-bridge-CkYcMxlq.mjs.map +1 -0
- package/dist/{chunk-BSw8zbkd.mjs → chunk-BEJ448es.mjs} +1 -3
- package/dist/cli-VNqUKlXw.mjs +4 -0
- package/dist/{context-BU5LkkIy.mjs → context-CEhuD1R_.mjs} +1 -1
- package/dist/{context-BU5LkkIy.mjs.map → context-CEhuD1R_.mjs.map} +1 -1
- package/dist/devtools-BF4IMumr.mjs +2 -0
- package/dist/{devtools-DcQjgyjL.mjs → devtools-td2AjFwc.mjs} +5 -5
- package/dist/{devtools-DcQjgyjL.mjs.map → devtools-td2AjFwc.mjs.map} +1 -1
- package/dist/{easing-BI-ASGMO.d.mts → easing-C5MrdO7V.d.mts} +1 -1
- package/dist/{easing-BI-ASGMO.d.mts.map → easing-C5MrdO7V.d.mts.map} +1 -1
- package/dist/{eta-CJlGH06n.mjs → eta-BwYWEjfS.mjs} +1 -1
- package/dist/{eta-CJlGH06n.mjs.map → eta-BwYWEjfS.mjs.map} +1 -1
- package/dist/{flexily-zero-adapter-C4lW_Ov5.mjs → flexily-zero-adapter-DktX3HsX.mjs} +1 -1
- package/dist/{flexily-zero-adapter-C3Vj0fPt.mjs → flexily-zero-adapter-VoBGHG14.mjs} +1 -1
- package/dist/{flexily-zero-adapter-C3Vj0fPt.mjs.map → flexily-zero-adapter-VoBGHG14.mjs.map} +1 -1
- package/dist/hit-registry-D_nxOivS.d.mts +71 -0
- package/dist/hit-registry-D_nxOivS.d.mts.map +1 -0
- package/dist/{UPNG-DosRPdF4.mjs → image-CIF75xMr.mjs} +891 -6
- package/dist/image-CIF75xMr.mjs.map +1 -0
- package/dist/{index-CSQf13CI.d.mts → index-377zdPLP.d.mts} +35 -12
- package/dist/index-377zdPLP.d.mts.map +1 -0
- package/dist/{index-Cl9KKjQ_.d.mts → index-BcSr0RAQ.d.mts} +8670 -10659
- package/dist/index-BcSr0RAQ.d.mts.map +1 -0
- package/dist/{index-XbNrPhWl.d.mts → index-DLnpxDAm.d.mts} +2 -2
- package/dist/{index-XbNrPhWl.d.mts.map → index-DLnpxDAm.d.mts.map} +1 -1
- package/dist/{index-BUMxS65f.d.mts → index-DlNmckTq.d.mts} +2 -2
- package/dist/{index-BUMxS65f.d.mts.map → index-DlNmckTq.d.mts.map} +1 -1
- package/dist/index.d.mts +12 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +18 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{layout-engine-C2px0RJE.mjs → layout-engine-BgR58vL0.mjs} +3 -3
- package/dist/{layout-engine-C2px0RJE.mjs.map → layout-engine-BgR58vL0.mjs.map} +1 -1
- package/dist/{layout-engine-C07LEXWT.mjs → layout-engine-DNjTha8f.mjs} +1 -1
- package/dist/{layout-signals-Cnw6xk8Q.mjs → layout-signals-CGYbHmxy.mjs} +146 -23
- package/dist/layout-signals-CGYbHmxy.mjs.map +1 -0
- package/dist/{bound-term-0sPrrzH1.d.mts → mouse-events-B2z5tbsL.d.mts} +780 -379
- package/dist/mouse-events-B2z5tbsL.d.mts.map +1 -0
- package/dist/{mouse-events-Dki3ISIp.mjs → mouse-events-WQ2h-uqG.mjs} +45 -10
- package/dist/mouse-events-WQ2h-uqG.mjs.map +1 -0
- package/dist/{multi-progress-DHZ2xUT2.d.mts → multi-progress-BaEFfHKP.d.mts} +2 -2
- package/dist/{multi-progress-DHZ2xUT2.d.mts.map → multi-progress-BaEFfHKP.d.mts.map} +1 -1
- package/dist/{multi-progress-CIRjrzma.mjs → multi-progress-zCWHEm9P.mjs} +3 -3
- package/dist/{multi-progress-CIRjrzma.mjs.map → multi-progress-zCWHEm9P.mjs.map} +1 -1
- package/dist/{node-CjM5Rt-M.mjs → node-CJ3J_rW-.mjs} +1 -1
- package/dist/{node-CjM5Rt-M.mjs.map → node-CJ3J_rW-.mjs.map} +1 -1
- package/dist/{progress-DB_Xo071.mjs → progress-6vJ7nxUg.mjs} +4 -4
- package/dist/{progress-DB_Xo071.mjs.map → progress-6vJ7nxUg.mjs.map} +1 -1
- package/dist/{progress-bar-oJwq22CR.mjs → progress-bar-BlFNsZL8.mjs} +4 -4
- package/dist/{progress-bar-oJwq22CR.mjs.map → progress-bar-BlFNsZL8.mjs.map} +1 -1
- package/dist/{reconciler-DldIJB93.mjs → reconciler--_-biN23.mjs} +190 -134
- package/dist/reconciler--_-biN23.mjs.map +1 -0
- package/dist/{render-string-BcoCpjCB.mjs → render-string-DaghHpLN.mjs} +1 -1
- package/dist/render-string-DtHZP0cU.mjs +215 -0
- package/dist/render-string-DtHZP0cU.mjs.map +1 -0
- package/dist/runtime.d.mts +4 -3
- package/dist/runtime.mjs +4 -3
- package/dist/schemes-DWQPxXAi.mjs +2516 -0
- package/dist/{schemes-JjNp4aSl.mjs.map → schemes-DWQPxXAi.mjs.map} +1 -1
- package/dist/{spinner-D9lrHr8s.mjs → spinner-B50hILqx.mjs} +19 -4
- package/dist/{spinner-D9lrHr8s.mjs.map → spinner-B50hILqx.mjs.map} +1 -1
- package/dist/{spinner-CZINHpkV.d.mts → spinner-DN10UfF0.d.mts} +2 -2
- package/dist/{spinner-CZINHpkV.d.mts.map → spinner-DN10UfF0.d.mts.map} +1 -1
- package/dist/{src-BNTToU7l.mjs → src-B8lf1kiR.mjs} +1507 -1166
- package/dist/src-B8lf1kiR.mjs.map +1 -0
- package/dist/{src-5w9QR6_8.mjs → src-BOLdi3WG.mjs} +105 -237
- package/dist/src-BOLdi3WG.mjs.map +1 -0
- package/dist/{src-BR4xNwdG.mjs → src-BXeTHHlL.mjs} +20240 -25437
- package/dist/src-BXeTHHlL.mjs.map +1 -0
- package/dist/{src-DKp-_OFG.mjs → src-BqeBFB3X.mjs} +90 -47
- package/dist/src-BqeBFB3X.mjs.map +1 -0
- package/dist/src-DbqcSrhy.mjs +3901 -0
- package/dist/src-DbqcSrhy.mjs.map +1 -0
- package/dist/{steps-Bp2uNqnn.d.mts → steps-B2kBmFpb.d.mts} +1 -1
- package/dist/{steps-Bp2uNqnn.d.mts.map → steps-B2kBmFpb.d.mts.map} +1 -1
- package/dist/{svg-Cz0UXcDj.mjs → svg-NmV9dgB9.mjs} +1 -1
- package/dist/{svg-Cz0UXcDj.mjs.map → svg-NmV9dgB9.mjs.map} +1 -1
- package/dist/{svg-g1D6ErwR.d.mts → svg-VUr78l5d.d.mts} +1 -1
- package/dist/{svg-g1D6ErwR.d.mts.map → svg-VUr78l5d.d.mts.map} +1 -1
- package/dist/term.d.mts +2 -2
- package/dist/term.mjs +3 -8
- package/dist/test.d.mts +673 -0
- package/dist/test.d.mts.map +1 -0
- package/dist/test.mjs +2829 -0
- package/dist/test.mjs.map +1 -0
- package/dist/theme.d.mts +2 -2
- package/dist/theme.d.mts.map +1 -1
- package/dist/theme.mjs +3 -8
- package/dist/{types-kt_fKR37.d.mts → types-D_E0FbqA.d.mts} +1 -1
- package/dist/{types-kt_fKR37.d.mts.map → types-D_E0FbqA.d.mts.map} +1 -1
- package/dist/ui/animation.d.mts +2 -2
- package/dist/ui/animation.mjs +1 -1
- package/dist/ui/ansi.d.mts +1 -1
- package/dist/ui/ansi.mjs +1 -1
- package/dist/ui/cli.d.mts +3 -3
- package/dist/ui/cli.mjs +5 -5
- package/dist/ui/image.d.mts +1 -1
- package/dist/ui/image.mjs +1 -1
- package/dist/ui/progress.d.mts +4 -4
- package/dist/ui/progress.mjs +4 -4
- package/dist/ui/react.d.mts +1 -1
- package/dist/ui/react.mjs +2 -2
- package/dist/ui/recording-chrome-react.d.mts +1 -1
- package/dist/ui/recording-chrome-react.mjs +2 -2
- package/dist/ui/recording-chrome.d.mts +1 -1
- package/dist/ui/recording-chrome.mjs +1 -1
- package/dist/ui/utils.mjs +1 -1
- package/dist/ui/wrappers.d.mts +2 -2
- package/dist/ui/wrappers.mjs +1 -1
- package/dist/ui.d.mts +6 -6
- package/dist/ui.mjs +7 -7
- package/dist/unicode-CxyxVGmB.mjs +11077 -0
- package/dist/unicode-CxyxVGmB.mjs.map +1 -0
- package/dist/{useLatest-DRDDVwjh.d.mts → useLatest-UOvWy0ZW.d.mts} +2 -2
- package/dist/{useLatest-DRDDVwjh.d.mts.map → useLatest-UOvWy0ZW.d.mts.map} +1 -1
- package/dist/useLayout-D5cE8OCI.mjs +424 -0
- package/dist/useLayout-D5cE8OCI.mjs.map +1 -0
- package/dist/{with-text-input-YeohVLeo.d.mts → with-text-input-DLoSCBrm.d.mts} +3 -3
- package/dist/{with-text-input-YeohVLeo.d.mts.map → with-text-input-DLoSCBrm.d.mts.map} +1 -1
- package/dist/wrap-measurer-registration-IV2HtcCd.d.mts +3106 -0
- package/dist/wrap-measurer-registration-IV2HtcCd.d.mts.map +1 -0
- package/dist/{wrapper-C70ATkVv.mjs → wrapper-CD29afOs.mjs} +59 -17
- package/dist/wrapper-CD29afOs.mjs.map +1 -0
- package/dist/{wrappers-BCUYITrY.mjs → wrappers-CInBJm44.mjs} +18 -8
- package/dist/wrappers-CInBJm44.mjs.map +1 -0
- package/dist/{yoga-adapter-BnZX1PAY.mjs → yoga-adapter-9uab5Qn-.mjs} +2 -2
- package/dist/{yoga-adapter-BnZX1PAY.mjs.map → yoga-adapter-9uab5Qn-.mjs.map} +1 -1
- package/dist/yoga-adapter-yqTl1aXK.mjs +2 -0
- package/package.json +59 -14
- package/dist/Text-Lq0dmj8-.mjs.map +0 -1
- package/dist/UPNG-Bo33r8rA.mjs +0 -3
- package/dist/UPNG-DosRPdF4.mjs.map +0 -1
- package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs +0 -6
- package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs.map +0 -1
- package/dist/ansi-yC4RyBNY.mjs +0 -22441
- package/dist/ansi-yC4RyBNY.mjs.map +0 -1
- package/dist/apng-CR08rIaH.mjs +0 -58
- package/dist/apng-CR08rIaH.mjs.map +0 -1
- package/dist/apng-DaHfVaVI.mjs +0 -3
- package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
- package/dist/assets/skia.darwin-arm64-DQs5sT6N.node +0 -0
- package/dist/backends-CUtan80W.mjs +0 -3
- package/dist/backends-DIVYzKqd.mjs +0 -1083
- package/dist/backends-DIVYzKqd.mjs.map +0 -1
- package/dist/bound-term-0sPrrzH1.d.mts.map +0 -1
- package/dist/canvas-1v7dPT-_.mjs +0 -3
- package/dist/canvas-CSuPOMNt.mjs +0 -1442
- package/dist/canvas-CSuPOMNt.mjs.map +0 -1
- package/dist/cli-dvo0r2fs.mjs +0 -4
- package/dist/compare-CQodSH4G.mjs +0 -376
- package/dist/compare-CQodSH4G.mjs.map +0 -1
- package/dist/compare-DHlcxEYA.mjs +0 -3
- package/dist/devtools-CJdt5H0X.mjs +0 -2
- package/dist/fonts-BFmhXDv7.mjs +0 -88
- package/dist/fonts-BFmhXDv7.mjs.map +0 -1
- package/dist/gif-C_AjaT9d.mjs +0 -188
- package/dist/gif-C_AjaT9d.mjs.map +0 -1
- package/dist/gif-DaC4XrxA.mjs +0 -3
- package/dist/gifenc-BOUT-KFB.mjs +0 -730
- package/dist/gifenc-BOUT-KFB.mjs.map +0 -1
- package/dist/image-C2Birh2x.mjs +0 -1252
- package/dist/image-C2Birh2x.mjs.map +0 -1
- package/dist/index-CSQf13CI.d.mts.map +0 -1
- package/dist/index-Cl9KKjQ_.d.mts.map +0 -1
- package/dist/key-mapping-CS-YD_cD.mjs +0 -132
- package/dist/key-mapping-CS-YD_cD.mjs.map +0 -1
- package/dist/key-mapping-Yn-Jgrij.mjs +0 -3
- package/dist/layout-signals-Cnw6xk8Q.mjs.map +0 -1
- package/dist/mouse-events-Dki3ISIp.mjs.map +0 -1
- package/dist/playwright-D5YiZcNS.mjs +0 -76397
- package/dist/playwright-D5YiZcNS.mjs.map +0 -1
- package/dist/png-codec-Dp84742B.mjs +0 -36
- package/dist/png-codec-Dp84742B.mjs.map +0 -1
- package/dist/png-codec-QwOtJ8Zs.mjs +0 -3
- package/dist/rasterizer-BRXrDdWx.mjs +0 -3
- package/dist/rasterizer-CpEhJvdR.mjs +0 -296
- package/dist/rasterizer-CpEhJvdR.mjs.map +0 -1
- package/dist/reconciler-DldIJB93.mjs.map +0 -1
- package/dist/render-string-DkQacASz.mjs.map +0 -1
- package/dist/resvg-js-DkOndZI3.mjs +0 -203
- package/dist/resvg-js-DkOndZI3.mjs.map +0 -1
- package/dist/schemes-JjNp4aSl.mjs +0 -2611
- package/dist/src-5w9QR6_8.mjs.map +0 -1
- package/dist/src-BNTToU7l.mjs.map +0 -1
- package/dist/src-BR4xNwdG.mjs.map +0 -1
- package/dist/src-DKp-_OFG.mjs.map +0 -1
- package/dist/src-bt8wSrfJ.mjs +0 -258
- package/dist/src-bt8wSrfJ.mjs.map +0 -1
- package/dist/src-e33Y6kNJ.mjs +0 -3
- package/dist/src-iDwu25UD.mjs +0 -1814
- package/dist/src-iDwu25UD.mjs.map +0 -1
- package/dist/svg-15lZZzxq.mjs +0 -486
- package/dist/svg-15lZZzxq.mjs.map +0 -1
- package/dist/svg-DY72a4HK.mjs +0 -3
- package/dist/term.mjs.map +0 -1
- package/dist/theme.mjs.map +0 -1
- package/dist/ui/display.d.mts +0 -35
- package/dist/ui/display.d.mts.map +0 -1
- package/dist/ui/display.mjs +0 -123
- package/dist/ui/display.mjs.map +0 -1
- package/dist/ui/input.d.mts +0 -184
- package/dist/ui/input.d.mts.map +0 -1
- package/dist/ui/input.mjs +0 -285
- package/dist/ui/input.mjs.map +0 -1
- package/dist/wrapper-C70ATkVv.mjs.map +0 -1
- package/dist/wrappers-BCUYITrY.mjs.map +0 -1
- package/dist/yoga-adapter-DxgsQ_gg.mjs +0 -2
- package/dist/zipBundle-3nqeDRtm.mjs +0 -3
- package/dist/zipBundle-VNAYFmqJ.mjs +0 -2003
- package/dist/zipBundle-VNAYFmqJ.mjs.map +0 -1
package/dist/test.d.mts
ADDED
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
import { F as TerminalCaps, Z as ColorScheme, ht as Theme } from "./index-377zdPLP.mjs";
|
|
2
|
+
import { $ as bufferToHTML, Qt as CODE_TO_KEY, S as Term, Y as Cell, Z as TerminalBuffer, _ as BoundTerm, an as keyToKittyAnsi, et as bufferToStyledText, ht as AgNode, in as keyToAnsi, jt as Rect, nt as FrameCell, rt as TextFrame, tt as bufferToText } from "./mouse-events-B2z5tbsL.mjs";
|
|
3
|
+
import { Bt as App, Gt as LayoutShift, Ht as FilterOptions, It as LayoutEngine, Kt as ReasonClassifier, Ut as createAutoLocator, Vt as AutoLocator, Wt as CLSReport, hr as stripAnsi, qt as ReflowReason } from "./wrap-measurer-registration-IV2HtcCd.mjs";
|
|
4
|
+
import React, { ReactElement } from "react";
|
|
5
|
+
|
|
6
|
+
//#region packages/ag-term/src/strict-cls.d.ts
|
|
7
|
+
/** SILVERY_STRICT slug for the CLS check. Tier 2 by design. */
|
|
8
|
+
declare const CLS_STRICT_SLUG = "cls";
|
|
9
|
+
declare const CLS_STRICT_MIN_TIER = 2;
|
|
10
|
+
/** Returns true when SILVERY_STRICT=cls (or =2 / =3 / etc.) is enabled. */
|
|
11
|
+
declare function isClsStrictEnabled(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Thrown when SILVERY_STRICT=cls is enabled and a capture window saw at
|
|
14
|
+
* least one shift with reflowReason="unexpected".
|
|
15
|
+
*
|
|
16
|
+
* Carries the offending shifts AND the cumulative unexpected-only score
|
|
17
|
+
* so failing tests can point at the worst offenders without rerunning.
|
|
18
|
+
* `.message` is human-readable; `.shifts` + `.score` are for programmatic
|
|
19
|
+
* inspection.
|
|
20
|
+
*/
|
|
21
|
+
declare class UnexpectedLayoutShiftError extends Error {
|
|
22
|
+
readonly shifts: readonly LayoutShift[];
|
|
23
|
+
readonly score: number;
|
|
24
|
+
constructor(shifts: readonly LayoutShift[], score: number);
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region packages/test/src/debug.d.ts
|
|
28
|
+
interface DebugTreeOptions {
|
|
29
|
+
/** Maximum depth to traverse (default: unlimited) */
|
|
30
|
+
depth?: number;
|
|
31
|
+
/** Include layout rectangles (default: true) */
|
|
32
|
+
showRects?: boolean;
|
|
33
|
+
/** Include text content (default: true) */
|
|
34
|
+
showText?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Pretty-print SilveryNode tree for debugging.
|
|
38
|
+
*
|
|
39
|
+
* @param node - Root node to inspect
|
|
40
|
+
* @param options - Display options
|
|
41
|
+
* @returns Formatted tree string
|
|
42
|
+
*/
|
|
43
|
+
declare function debugTree(node: AgNode, options?: DebugTreeOptions): string;
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region packages/test/src/diagnostic-theme.d.ts
|
|
46
|
+
/**
|
|
47
|
+
* Maximally-distinct ColorScheme for diagnostic rendering tests.
|
|
48
|
+
*
|
|
49
|
+
* Pure black canvas, pure white fg, saturated ANSI primaries. Every derived
|
|
50
|
+
* token gets a unique visible RGB.
|
|
51
|
+
*/
|
|
52
|
+
declare const diagnosticScheme: ColorScheme;
|
|
53
|
+
/**
|
|
54
|
+
* Pre-derived diagnostic theme. Pass to `createRenderer({ theme })` or
|
|
55
|
+
* `testBoard({ theme })` for pipeline regression coverage.
|
|
56
|
+
*/
|
|
57
|
+
declare const diagnosticTheme: Theme;
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region packages/test/src/compare-buffers.d.ts
|
|
60
|
+
/**
|
|
61
|
+
* A single cell mismatch between two buffers.
|
|
62
|
+
*/
|
|
63
|
+
interface BufferMismatch {
|
|
64
|
+
/** Column of the mismatched cell */
|
|
65
|
+
x: number;
|
|
66
|
+
/** Row of the mismatched cell */
|
|
67
|
+
y: number;
|
|
68
|
+
/** Cell from buffer A (e.g., incremental render) */
|
|
69
|
+
cellA: Cell;
|
|
70
|
+
/** Cell from buffer B (e.g., fresh render) */
|
|
71
|
+
cellB: Cell;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Compare two terminal buffers cell-by-cell.
|
|
75
|
+
*
|
|
76
|
+
* @returns The first mismatch found, or null if buffers are identical.
|
|
77
|
+
*/
|
|
78
|
+
declare function compareBuffers(a: TerminalBuffer, b: TerminalBuffer): BufferMismatch | null;
|
|
79
|
+
/**
|
|
80
|
+
* Format a buffer mismatch for human-readable error output.
|
|
81
|
+
*/
|
|
82
|
+
declare function formatMismatch(mismatch: BufferMismatch, context?: {
|
|
83
|
+
incrementalText?: string;
|
|
84
|
+
freshText?: string;
|
|
85
|
+
seed?: number;
|
|
86
|
+
iteration?: number;
|
|
87
|
+
key?: string;
|
|
88
|
+
}): string;
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region packages/test/src/cell-inspector.d.ts
|
|
91
|
+
interface TestCellSnapshot extends Cell {
|
|
92
|
+
readonly x: number;
|
|
93
|
+
readonly y: number;
|
|
94
|
+
readonly selectable: boolean;
|
|
95
|
+
}
|
|
96
|
+
declare function readCellSnapshot(buffer: TerminalBuffer, x: number, y: number): TestCellSnapshot;
|
|
97
|
+
declare function readCellRow(buffer: TerminalBuffer, y: number): TestCellSnapshot[];
|
|
98
|
+
declare function formatSelectableCells(buffer: TerminalBuffer): string;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region packages/test/src/frame-recorder.d.ts
|
|
101
|
+
/**
|
|
102
|
+
* A single cell change between two frames at the same (col, row).
|
|
103
|
+
*
|
|
104
|
+
* `from` and `to` are the cell states in the "before" and "after" frames.
|
|
105
|
+
* Both are always present — to detect appearance/disappearance, compare
|
|
106
|
+
* `char`, `fg`, or `bg` against the blank-cell defaults.
|
|
107
|
+
*/
|
|
108
|
+
interface CellChange {
|
|
109
|
+
readonly col: number;
|
|
110
|
+
readonly row: number;
|
|
111
|
+
readonly from: FrameCell;
|
|
112
|
+
readonly to: FrameCell;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A predicate over three consecutive frames. Returns true when the cell at
|
|
116
|
+
* some coordinate changes in frame B and reverts in frame C — the signature
|
|
117
|
+
* of a 1-frame transient flicker.
|
|
118
|
+
*/
|
|
119
|
+
type TransientPredicate = (a: TextFrame, b: TextFrame, c: TextFrame) => boolean;
|
|
120
|
+
/**
|
|
121
|
+
* A live recording of rendered frames.
|
|
122
|
+
*
|
|
123
|
+
* `frames` is an append-only array of immutable TextFrame snapshots. Each
|
|
124
|
+
* entry captures the terminal state after one render pass. Subsequent renders
|
|
125
|
+
* push new entries without mutating existing ones, so tests can safely iterate
|
|
126
|
+
* and diff across history.
|
|
127
|
+
*/
|
|
128
|
+
interface FrameRecording {
|
|
129
|
+
/** All captured frames, in render order. */
|
|
130
|
+
readonly frames: readonly TextFrame[];
|
|
131
|
+
/** Convenience: `frames.length`. */
|
|
132
|
+
readonly count: number;
|
|
133
|
+
/**
|
|
134
|
+
* Cells that differ between frames `i` and `j`. Returns an empty array when
|
|
135
|
+
* the frames are identical. Size mismatches (frames captured at different
|
|
136
|
+
* terminal dimensions) are diffed over the intersection.
|
|
137
|
+
*/
|
|
138
|
+
diff(i: number, j: number): CellChange[];
|
|
139
|
+
/**
|
|
140
|
+
* Scan every 3-frame window for transient changes. Returns true when the
|
|
141
|
+
* predicate fires on any `(frames[i], frames[i+1], frames[i+2])` triple.
|
|
142
|
+
*
|
|
143
|
+
* A transient change is a cell that changes in one frame and reverts in the
|
|
144
|
+
* next — the visual signature of a flicker, stale overlay, or one-frame
|
|
145
|
+
* paint bug.
|
|
146
|
+
*/
|
|
147
|
+
hasTransientChange(predicate: TransientPredicate): boolean;
|
|
148
|
+
/** Clear all recorded frames. Useful between test phases. */
|
|
149
|
+
clear(): void;
|
|
150
|
+
/** Stop recording. Frames already captured remain accessible. */
|
|
151
|
+
stop(): void;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* A handle-like object that exposes a Term. Accepted by `recordFrames()` in
|
|
155
|
+
* addition to a bare Term.
|
|
156
|
+
*/
|
|
157
|
+
interface FrameRecordable {
|
|
158
|
+
readonly term: Term;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Start recording frames from a Term (or any object exposing `.term`).
|
|
162
|
+
*
|
|
163
|
+
* The recorder observes the emulator's ANSI feed so that every render patch
|
|
164
|
+
* triggers a fresh TextFrame snapshot. Only calls made AFTER `recordFrames()`
|
|
165
|
+
* returns are captured — the initial render is not retroactively recorded.
|
|
166
|
+
* Call `recording.stop()` to end recording early.
|
|
167
|
+
*
|
|
168
|
+
* For emulator-backed terms created via `createTermless()`, snapshots reflect
|
|
169
|
+
* the real terminal state including resolved colors and wide characters. For
|
|
170
|
+
* other Term types, this function throws — cell-level recording requires an
|
|
171
|
+
* emulator.
|
|
172
|
+
*/
|
|
173
|
+
declare function recordFrames(target: Term | FrameRecordable): FrameRecording;
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region packages/ag-term/src/renderer.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* Options for headless render (no terminal).
|
|
178
|
+
*/
|
|
179
|
+
interface RenderOptions {
|
|
180
|
+
/** Terminal width for layout. Default: 80 */
|
|
181
|
+
cols?: number;
|
|
182
|
+
/** Terminal height for layout. Default: 24 */
|
|
183
|
+
rows?: number;
|
|
184
|
+
/** Layout engine to use. Default: current global engine */
|
|
185
|
+
layoutEngine?: LayoutEngine;
|
|
186
|
+
/** Enable debug output. Default: false */
|
|
187
|
+
debug?: boolean;
|
|
188
|
+
/** Enable incremental rendering. Default: true */
|
|
189
|
+
incremental?: boolean;
|
|
190
|
+
/** Use Kitty keyboard protocol encoding for press(). When true, press() uses keyToKittyAnsi. */
|
|
191
|
+
kittyMode?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Handle Tab / Shift+Tab as focus-cycling keystrokes in `sendInput`/`press`.
|
|
194
|
+
* When `false`, Tab and Shift+Tab reach `useInput` instead of being consumed
|
|
195
|
+
* by the focus manager — matching the production `run()` option of the same
|
|
196
|
+
* name (Claude-Code-style "Shift+Tab cycles permission mode" apps).
|
|
197
|
+
*
|
|
198
|
+
* Default: true.
|
|
199
|
+
*/
|
|
200
|
+
handleTabCycling?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Maximum layout-pass iterations per render. Each pass: runPipeline +
|
|
203
|
+
* flushSyncWork. Loop exits when no React commit happens (converged) or
|
|
204
|
+
* when the cap is reached.
|
|
205
|
+
*
|
|
206
|
+
* Default: `MAX_CONVERGENCE_PASSES` (2 — production-derived structural
|
|
207
|
+
* bound: 1 initial + 1 settle for measurement feedback).
|
|
208
|
+
*
|
|
209
|
+
* Tests that depend on multi-iteration stabilization (e.g. legacy
|
|
210
|
+
* scrollable-list virtualization that previously relied on the classic
|
|
211
|
+
* 5-iteration loop) can opt into a higher cap via `maxLayoutPasses: 5`.
|
|
212
|
+
*
|
|
213
|
+
* See pass-cause.ts:MAX_CONVERGENCE_PASSES for the structural derivation
|
|
214
|
+
* and bead `@km/silvery/renderer-convergence-by-design` for the convergence
|
|
215
|
+
* theorem.
|
|
216
|
+
*/
|
|
217
|
+
maxLayoutPasses?: number;
|
|
218
|
+
/**
|
|
219
|
+
* Auto-render on async React commits (e.g., setTimeout → setState).
|
|
220
|
+
*
|
|
221
|
+
* When true, the renderer schedules a microtask re-render whenever React
|
|
222
|
+
* commits new work outside of explicit render/sendInput/rerender calls.
|
|
223
|
+
* This enables test components with async state updates to produce new
|
|
224
|
+
* frames automatically.
|
|
225
|
+
*
|
|
226
|
+
* Default: false (renderer only renders on explicit triggers).
|
|
227
|
+
*/
|
|
228
|
+
autoRender?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Callback fired after each frame render.
|
|
231
|
+
*
|
|
232
|
+
* Called with the frame output string and the underlying TerminalBuffer.
|
|
233
|
+
* Fires after initial render, sendInput, rerender, and (if autoRender)
|
|
234
|
+
* async state changes.
|
|
235
|
+
*/
|
|
236
|
+
onFrame?: (frame: string, buffer: TerminalBuffer, contentHeight?: number) => void;
|
|
237
|
+
/**
|
|
238
|
+
* Callback fired after each pipeline execution, before React effects flush.
|
|
239
|
+
*
|
|
240
|
+
* Called inside act() after runPipeline produces the buffer but before
|
|
241
|
+
* useLayoutEffect/useEffect callbacks run. Use this to make pipeline output
|
|
242
|
+
* available to effects (e.g., Ink compat debug mode where useStdout().write()
|
|
243
|
+
* needs to replay the latest frame).
|
|
244
|
+
*/
|
|
245
|
+
onBufferReady?: (frame: string, buffer: TerminalBuffer, contentHeight?: number) => void;
|
|
246
|
+
/**
|
|
247
|
+
* Wrap the root element with additional providers.
|
|
248
|
+
* Called with the element after silvery's internal contexts are applied.
|
|
249
|
+
* Use this to inject additional context providers (e.g., Ink compatibility wrappers).
|
|
250
|
+
* The wrapper is applied INSIDE silvery's contexts, so wrapped providers
|
|
251
|
+
* can access silvery's Term, Stdout, FocusManager, and Runtime contexts.
|
|
252
|
+
*/
|
|
253
|
+
wrapRoot?: (element: React.ReactElement) => React.ReactElement;
|
|
254
|
+
/**
|
|
255
|
+
* External stdin stream to bridge to the renderer's input.
|
|
256
|
+
* When provided, readable data from this stream is forwarded to the renderer's
|
|
257
|
+
* input handler (equivalent to calling app.stdin.write()).
|
|
258
|
+
*/
|
|
259
|
+
stdin?: NodeJS.ReadStream;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Store — the TermDef-like environment for render().
|
|
263
|
+
* Provides cols, rows, and optionally an event stream for interactive mode.
|
|
264
|
+
*/
|
|
265
|
+
interface Store {
|
|
266
|
+
/** Terminal columns */
|
|
267
|
+
readonly cols: number;
|
|
268
|
+
/** Terminal rows */
|
|
269
|
+
readonly rows: number;
|
|
270
|
+
/** Async event stream (if present, enables interactive mode) */
|
|
271
|
+
events?(): AsyncIterable<StoreEvent>;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Event from a store's event stream.
|
|
275
|
+
*/
|
|
276
|
+
interface StoreEvent {
|
|
277
|
+
type: string;
|
|
278
|
+
data: unknown;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Provider options for createStore().
|
|
282
|
+
*/
|
|
283
|
+
interface StoreOptions {
|
|
284
|
+
/** Terminal columns. Default: 80 */
|
|
285
|
+
cols?: number;
|
|
286
|
+
/** Terminal rows. Default: 24 */
|
|
287
|
+
rows?: number;
|
|
288
|
+
/** Event source for interactive mode */
|
|
289
|
+
events?: AsyncIterable<StoreEvent>;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Ensure layout engine is initialized (async, cached).
|
|
293
|
+
*/
|
|
294
|
+
declare function ensureEngine(): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Render a React element synchronously. Returns a full App with locators,
|
|
297
|
+
* press(), text, ansi, etc.
|
|
298
|
+
*
|
|
299
|
+
* Layout engine must be initialized before calling (use ensureEngine() or
|
|
300
|
+
* the top-level await in testing module).
|
|
301
|
+
*
|
|
302
|
+
* Overloads:
|
|
303
|
+
* - render(element, { cols, rows }) — headless with dimensions
|
|
304
|
+
* - render(element, store) — with a Store from createStore()
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```tsx
|
|
308
|
+
* const app = render(<Counter />, { cols: 80, rows: 24 })
|
|
309
|
+
* expect(app.text).toContain('Count: 0')
|
|
310
|
+
* await app.press('j')
|
|
311
|
+
* expect(app.text).toContain('Count: 1')
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
declare function render(element: ReactElement, optsOrStore?: RenderOptions | Store): App;
|
|
315
|
+
/**
|
|
316
|
+
* Create a Store from provider options.
|
|
317
|
+
*
|
|
318
|
+
* A Store is the TermDef-like environment: cols, rows, and optionally events.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```tsx
|
|
322
|
+
* const store = createStore({ cols: 80, rows: 24 })
|
|
323
|
+
* const app = render(<App />, store)
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
declare function createStore(options?: StoreOptions): Store;
|
|
327
|
+
/**
|
|
328
|
+
* Per-render overrides for createRenderer's returned function.
|
|
329
|
+
*/
|
|
330
|
+
interface PerRenderOptions {
|
|
331
|
+
/** Enable incremental rendering for this render. */
|
|
332
|
+
incremental?: boolean;
|
|
333
|
+
/** Max layout-pass iterations per render. See RenderOptions.maxLayoutPasses. */
|
|
334
|
+
maxLayoutPasses?: number;
|
|
335
|
+
/** Use Kitty keyboard protocol encoding for press(). */
|
|
336
|
+
kittyMode?: boolean;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Create a render function that auto-cleans previous renders.
|
|
340
|
+
*
|
|
341
|
+
* By default, incremental rendering is ENABLED for test renders.
|
|
342
|
+
* This matches production behavior (live scheduler uses incremental)
|
|
343
|
+
* and enables withDiagnostics to catch incremental vs fresh mismatches.
|
|
344
|
+
*
|
|
345
|
+
* **Instance reuse:** When the same renderer is called repeatedly with a
|
|
346
|
+
* compatible element (no overrides that would require fresh state), the
|
|
347
|
+
* returned function calls `current.rerender(element)` instead of
|
|
348
|
+
* unmount+remount. This avoids paying the full React reconciler init +
|
|
349
|
+
* fiberRoot creation cost on each iteration — which otherwise dominates
|
|
350
|
+
* cold-render microbenchmarks. See bead `km-silvery.renderer-reuse`.
|
|
351
|
+
*
|
|
352
|
+
* Reuse is skipped (forcing fresh mount) when:
|
|
353
|
+
* - The previous instance has been unmounted (rerender would throw)
|
|
354
|
+
* - Per-render overrides are supplied that conflict with baseOpts
|
|
355
|
+
* (e.g., flipping `incremental`, `maxLayoutPasses`, or `kittyMode`)
|
|
356
|
+
* - The base options are a Store (store-mode renders manage their own
|
|
357
|
+
* lifecycle and we conservatively force a fresh mount)
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```tsx
|
|
361
|
+
* const render = createRenderer({ cols: 80, rows: 24 })
|
|
362
|
+
* const app1 = render(<Foo />) // fresh mount
|
|
363
|
+
* const app2 = render(<Bar />) // reuses app1 via rerender()
|
|
364
|
+
* // app1 === app2 when reuse kicks in
|
|
365
|
+
*
|
|
366
|
+
* // Explicitly disable incremental if needed
|
|
367
|
+
* const render2 = createRenderer({ cols: 80, rows: 24, incremental: false })
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
declare function createRenderer(optsOrStore?: RenderOptions | Store): (el: ReactElement, overrides?: PerRenderOptions) => App;
|
|
371
|
+
/**
|
|
372
|
+
* Result of run() with sync events — iterable over events.
|
|
373
|
+
*/
|
|
374
|
+
interface SyncRunResult extends Iterable<string> {
|
|
375
|
+
/** Current rendered text */
|
|
376
|
+
readonly text: string;
|
|
377
|
+
/** The app being driven */
|
|
378
|
+
readonly app: App;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Result of run() with async events — async iterable and awaitable.
|
|
382
|
+
*/
|
|
383
|
+
interface AsyncRunResult extends AsyncIterable<string>, PromiseLike<void> {
|
|
384
|
+
/** Current rendered text */
|
|
385
|
+
readonly text: string;
|
|
386
|
+
/** The app being driven */
|
|
387
|
+
readonly app: App;
|
|
388
|
+
/** Unmount and stop the event loop */
|
|
389
|
+
unmount(): void;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Drive an App with events.
|
|
393
|
+
*
|
|
394
|
+
* - `run(app, ['j', 'k', 'Enter'])` — sync, explicit key events
|
|
395
|
+
* - `run(app, syncIterable)` — sync iteration over events
|
|
396
|
+
* - `await run(app)` — async, reads events from store (if rendered with one)
|
|
397
|
+
* - `for await (const text of run(app, asyncEvents))` — async iteration
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```tsx
|
|
401
|
+
* const app = render(<Counter />, { cols: 80, rows: 24 })
|
|
402
|
+
* run(app, ['j', 'k', 'Enter'])
|
|
403
|
+
* expect(app.text).toContain('Count: 2')
|
|
404
|
+
* ```
|
|
405
|
+
*/
|
|
406
|
+
declare function run(app: App, events: string[]): SyncRunResult;
|
|
407
|
+
declare function run(app: App, events: Iterable<string>): SyncRunResult;
|
|
408
|
+
declare function run(app: App, events?: AsyncIterable<string>): AsyncRunResult;
|
|
409
|
+
/**
|
|
410
|
+
* Get the number of currently active (mounted) render instances.
|
|
411
|
+
* Useful for tests to verify cleanup.
|
|
412
|
+
*/
|
|
413
|
+
declare function getActiveRenderCount(): number;
|
|
414
|
+
//#endregion
|
|
415
|
+
//#region packages/test/src/index.d.ts
|
|
416
|
+
/**
|
|
417
|
+
* Return the current count of live (un-GC'd) termless Term instances.
|
|
418
|
+
* Exported for tests that want to assert cleanup happened.
|
|
419
|
+
*/
|
|
420
|
+
declare function getActiveTermlessCount(): number;
|
|
421
|
+
/** Modifier keys for synthetic mouse events (matches termless MouseModifiers). */
|
|
422
|
+
interface TermlessMouseModifiers {
|
|
423
|
+
ctrl?: boolean;
|
|
424
|
+
shift?: boolean;
|
|
425
|
+
alt?: boolean;
|
|
426
|
+
/** SGR mouse uses the same modifier bit for Meta and Alt. */
|
|
427
|
+
meta?: boolean;
|
|
428
|
+
}
|
|
429
|
+
/** Options for a mouse event (button + modifiers). */
|
|
430
|
+
interface TermlessMouseOptions extends TermlessMouseModifiers {
|
|
431
|
+
/** 0=left (default), 1=middle, 2=right */
|
|
432
|
+
button?: 0 | 1 | 2;
|
|
433
|
+
}
|
|
434
|
+
/** Pixel-coordinate pair, 0-indexed. */
|
|
435
|
+
type TermlessPoint = [x: number, y: number];
|
|
436
|
+
type TermlessMouseCoordinateMode = "auto" | "cell" | "pixel";
|
|
437
|
+
type TermlessWheelDirection = "up" | "down";
|
|
438
|
+
interface TermlessMouseCellSize {
|
|
439
|
+
width: number;
|
|
440
|
+
height: number;
|
|
441
|
+
}
|
|
442
|
+
interface TermlessTrackpadFlickPacket {
|
|
443
|
+
/** Relative delivery time from gesture start. Packets with the same value are one stdin chunk. */
|
|
444
|
+
atMs: number;
|
|
445
|
+
/** Number of identical wheel reports in this packet. Preferred spelling for new tests. */
|
|
446
|
+
count?: number;
|
|
447
|
+
/** Compatibility alias for older gesture fixtures. */
|
|
448
|
+
events?: number;
|
|
449
|
+
/** Wheel delta sign; negative = up, positive = down. Also supplies count when count/events are omitted. */
|
|
450
|
+
delta?: number;
|
|
451
|
+
/** Exact SGR wheel button byte for terminal captures: 64 up, 65 down, 66 left, 67 right. */
|
|
452
|
+
button?: number;
|
|
453
|
+
/** Direction override for this packet. */
|
|
454
|
+
direction?: TermlessWheelDirection;
|
|
455
|
+
/** Cell coordinate override for this packet. */
|
|
456
|
+
x?: number;
|
|
457
|
+
/** Cell coordinate override for this packet. */
|
|
458
|
+
y?: number;
|
|
459
|
+
}
|
|
460
|
+
interface TermlessTrackpadFlickProfile {
|
|
461
|
+
/** Cell coordinate under the pointer. Pixel mode converts this through cellSize. */
|
|
462
|
+
x: number;
|
|
463
|
+
/** Cell coordinate under the pointer. Pixel mode converts this through cellSize. */
|
|
464
|
+
y: number;
|
|
465
|
+
direction?: TermlessWheelDirection;
|
|
466
|
+
/**
|
|
467
|
+
* Coordinate mode for encoded SGR reports.
|
|
468
|
+
* - auto: mirror the app's negotiated SGR/SGR-Pixels mode
|
|
469
|
+
* - cell: force SGR cell coordinates
|
|
470
|
+
* - pixel: force SGR-Pixels coordinates using cellSize
|
|
471
|
+
*/
|
|
472
|
+
coordinateMode?: TermlessMouseCoordinateMode;
|
|
473
|
+
cellSize?: TermlessMouseCellSize;
|
|
474
|
+
settleMs?: number;
|
|
475
|
+
packets: readonly TermlessTrackpadFlickPacket[];
|
|
476
|
+
}
|
|
477
|
+
interface TermlessWheelOptions extends TermlessMouseModifiers {
|
|
478
|
+
/** Horizontal wheel delta. Negative = left, positive = right. */
|
|
479
|
+
deltaX?: number;
|
|
480
|
+
/** Vertical wheel delta. Negative = up, positive = down. */
|
|
481
|
+
deltaY?: number;
|
|
482
|
+
/** Compatibility alias for vertical wheel delta. */
|
|
483
|
+
lines?: number;
|
|
484
|
+
/** Delay between repeated reports. Default: 8ms, matching ~120Hz trackpad cadence. */
|
|
485
|
+
cadenceMs?: number;
|
|
486
|
+
/** Coordinate mode for encoded SGR reports. Defaults to auto-detect. */
|
|
487
|
+
coordinateMode?: TermlessMouseCoordinateMode;
|
|
488
|
+
cellSize?: TermlessMouseCellSize;
|
|
489
|
+
}
|
|
490
|
+
interface TermlessTrackpadFlickGroup {
|
|
491
|
+
index: number;
|
|
492
|
+
atMs: number;
|
|
493
|
+
packetCount: number;
|
|
494
|
+
eventCount: number;
|
|
495
|
+
deltaSum: number;
|
|
496
|
+
}
|
|
497
|
+
interface TermlessTrackpadFlickResult {
|
|
498
|
+
eventCount: number;
|
|
499
|
+
durationMs: number;
|
|
500
|
+
groups: readonly TermlessTrackpadFlickGroup[];
|
|
501
|
+
}
|
|
502
|
+
interface TermlessTrackpadFlickDebugLogOptions {
|
|
503
|
+
/** Default: "pixel" when SGR-Pixels cell size can be inferred, otherwise "cell". */
|
|
504
|
+
coordinateMode?: TermlessMouseCoordinateMode;
|
|
505
|
+
/** Override inferred cell size for SGR-Pixels logs. */
|
|
506
|
+
cellSize?: TermlessMouseCellSize;
|
|
507
|
+
/** Override profile x. Defaults to first parsed wheel event x. */
|
|
508
|
+
x?: number;
|
|
509
|
+
/** Override profile y. Defaults to first parsed wheel event y. */
|
|
510
|
+
y?: number;
|
|
511
|
+
}
|
|
512
|
+
declare function parseTermlessTrackpadFlickProfileFromDebugLog(logText: string, options?: TermlessTrackpadFlickDebugLogOptions): TermlessTrackpadFlickProfile;
|
|
513
|
+
interface TermlessTrackpadFlickOptions {
|
|
514
|
+
/** Called after each timed stdin chunk is delivered and the event loop yields once. */
|
|
515
|
+
afterGroup?: (group: TermlessTrackpadFlickGroup) => void | Promise<void>;
|
|
516
|
+
}
|
|
517
|
+
interface TermlessMouse {
|
|
518
|
+
/** Fire a mousedown (press only — no release). */
|
|
519
|
+
down(x: number, y: number, options?: TermlessMouseOptions): Promise<void>;
|
|
520
|
+
/** Fire a mouseup (release only — no press). */
|
|
521
|
+
up(x: number, y: number, options?: TermlessMouseOptions): Promise<void>;
|
|
522
|
+
/** Fire a mouse move to (x,y). Stateless — no press implied. */
|
|
523
|
+
move(x: number, y: number, options?: TermlessMouseOptions): Promise<void>;
|
|
524
|
+
/** Down then up at the same coordinate — a plain click, no drag. */
|
|
525
|
+
click(x: number, y: number, options?: TermlessMouseOptions): Promise<void>;
|
|
526
|
+
/** Two consecutive clicks at the same coordinate. */
|
|
527
|
+
dblclick(x: number, y: number, options?: TermlessMouseOptions): Promise<void>;
|
|
528
|
+
/**
|
|
529
|
+
* Drag from one cell to another with N intermediate moves. Dispatches
|
|
530
|
+
* `down(from)` → `move(...via)` → `move(to)` → `up(to)`. Waits briefly
|
|
531
|
+
* between steps so the event loop can process each before the next.
|
|
532
|
+
*
|
|
533
|
+
* @example drag(from: [5, 2], to: [20, 2]) // simple drag
|
|
534
|
+
* @example drag(from: [10, 0], to: [5, 0], via: [[20, 0]]) // forward then shrink back
|
|
535
|
+
*/
|
|
536
|
+
drag(opts: {
|
|
537
|
+
from: TermlessPoint;
|
|
538
|
+
to: TermlessPoint;
|
|
539
|
+
via?: TermlessPoint[];
|
|
540
|
+
options?: TermlessMouseOptions; /** ms between dispatch steps. Default: 20 */
|
|
541
|
+
stepDelay?: number;
|
|
542
|
+
}): Promise<void>;
|
|
543
|
+
/** Fire mouse wheel events at (x,y). Positive vertical delta = scroll down. */
|
|
544
|
+
wheel(x: number, y: number, deltaOrOptions: number | TermlessWheelOptions, options?: TermlessWheelOptions): Promise<void>;
|
|
545
|
+
/**
|
|
546
|
+
* Replay a real trackpad-style wheel gesture: timestamped packet groups,
|
|
547
|
+
* optional SGR-Pixels coordinates, and many wheel reports in one stdin chunk.
|
|
548
|
+
*/
|
|
549
|
+
trackpadFlick(profile: TermlessTrackpadFlickProfile, options?: TermlessTrackpadFlickOptions): Promise<TermlessTrackpadFlickResult>;
|
|
550
|
+
}
|
|
551
|
+
/** OSC 52 clipboard capture — every clipboard write during the Term's life. */
|
|
552
|
+
interface TermlessClipboard {
|
|
553
|
+
/** Last OSC 52 payload captured, or null if none. */
|
|
554
|
+
readonly last: string | null;
|
|
555
|
+
/** All OSC 52 payloads captured, in order. */
|
|
556
|
+
readonly all: readonly string[];
|
|
557
|
+
/** Drop all captured payloads (useful between test phases). */
|
|
558
|
+
clear(): void;
|
|
559
|
+
}
|
|
560
|
+
interface TermlessOutput {
|
|
561
|
+
getText(): string;
|
|
562
|
+
getChunks(): readonly string[];
|
|
563
|
+
containsOutput(text: string): boolean;
|
|
564
|
+
clear(): void;
|
|
565
|
+
}
|
|
566
|
+
interface TermlessReflowResidue {
|
|
567
|
+
/** Visible marker injected by the residue simulator when an app repaints without ED2. */
|
|
568
|
+
readonly marker: string;
|
|
569
|
+
/**
|
|
570
|
+
* Arm the residue simulator for the next terminal write. Resizes arm this
|
|
571
|
+
* automatically; call this to model cmux workspace/alt-screen restoration
|
|
572
|
+
* that reflows the terminal without changing dimensions.
|
|
573
|
+
*/
|
|
574
|
+
arm(): void;
|
|
575
|
+
/** Disarm the simulator without requiring a clear. */
|
|
576
|
+
clear(): void;
|
|
577
|
+
/** Whether the next non-clearing write will inject the marker. */
|
|
578
|
+
readonly armed: boolean;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Term augmented with mouse + clipboard test helpers.
|
|
582
|
+
*
|
|
583
|
+
* `createTermless()` always returns an emulator-backed term, so `screen`,
|
|
584
|
+
* `scrollback`, and `cell()` are guaranteed defined here (the `Term`
|
|
585
|
+
* interface marks them optional because non-emulator-backed Terms — Node
|
|
586
|
+
* stdout, headless — don't have them). Narrowing them to required removes
|
|
587
|
+
* the need for `!` non-null assertions at every test callsite.
|
|
588
|
+
*/
|
|
589
|
+
interface TermlessTerm extends Term {
|
|
590
|
+
readonly mouse: TermlessMouse;
|
|
591
|
+
readonly clipboard: TermlessClipboard;
|
|
592
|
+
readonly out: TermlessOutput;
|
|
593
|
+
readonly reflowResidue?: TermlessReflowResidue;
|
|
594
|
+
readonly screen: NonNullable<Term["screen"]>;
|
|
595
|
+
readonly scrollback: NonNullable<Term["scrollback"]>;
|
|
596
|
+
cell(row: number, col: number): {
|
|
597
|
+
readonly fg: unknown;
|
|
598
|
+
readonly bg: unknown;
|
|
599
|
+
readonly char: string;
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
type TermlessBackendChoice = "xterm" | "ghostty" | "ghostty-native";
|
|
603
|
+
/**
|
|
604
|
+
* Create a Term backed by a termless xterm.js emulator for full ANSI testing.
|
|
605
|
+
*
|
|
606
|
+
* Convenience wrapper around `createTerm(createXtermBackend(), dims)` that
|
|
607
|
+
* handles the xterm.js backend import. Use with `run()` to render components
|
|
608
|
+
* into a real terminal emulator in-process — no PTY, no timing issues.
|
|
609
|
+
*
|
|
610
|
+
* The returned Term exposes two testing conveniences:
|
|
611
|
+
* - `term.mouse.*` — ergonomic mouse API (click, drag, down/up/move, wheel)
|
|
612
|
+
* - `term.clipboard` — OSC 52 capture (`term.clipboard.last`, `.all`)
|
|
613
|
+
*
|
|
614
|
+
* **Always dispose with `using` or an explicit `term[Symbol.dispose]()`.**
|
|
615
|
+
* Without disposal, each call leaks the xterm.js Terminal (~1 MB scrollback
|
|
616
|
+
* per instance). This accumulated to 18-28 GB per vitest worker in CI before
|
|
617
|
+
* `km-silvery.termless-memleak` was fixed.
|
|
618
|
+
*
|
|
619
|
+
* @example Mouse drag + clipboard capture
|
|
620
|
+
* ```tsx
|
|
621
|
+
* using term = createTermless({ cols: 40, rows: 10 })
|
|
622
|
+
* const handle = await run(<App />, term, { selection: true, mouse: true })
|
|
623
|
+
*
|
|
624
|
+
* await term.mouse.drag({ from: [5, 2], to: [20, 2] })
|
|
625
|
+
* expect(term.clipboard.last).toContain("selected text")
|
|
626
|
+
* ```
|
|
627
|
+
*
|
|
628
|
+
* @example Plain click
|
|
629
|
+
* ```tsx
|
|
630
|
+
* await term.mouse.click(10, 5)
|
|
631
|
+
* await term.mouse.click(10, 5, { shift: true })
|
|
632
|
+
* ```
|
|
633
|
+
*
|
|
634
|
+
* @example Override capabilities (defaults-contract tests)
|
|
635
|
+
* ```tsx
|
|
636
|
+
* using term = createTermless({ cols: 80, rows: 24, caps: { colorLevel: '256' } })
|
|
637
|
+
* ```
|
|
638
|
+
*
|
|
639
|
+
* Without a `caps` override, `term.caps` is populated from `defaultCaps()`
|
|
640
|
+
* (truecolor / unicode / mouse). Callers that want a specific terminal
|
|
641
|
+
* profile for a test — Apple_Terminal's lack of `maybeWideEmojis`, Kitty's
|
|
642
|
+
* `kittyKeyboard`, etc. — can pass a `Partial<TerminalCaps>` here.
|
|
643
|
+
*/
|
|
644
|
+
declare function createTermless(dims?: {
|
|
645
|
+
cols: number;
|
|
646
|
+
rows: number;
|
|
647
|
+
caps?: Partial<TerminalCaps>;
|
|
648
|
+
backend?: TermlessBackendChoice;
|
|
649
|
+
reflowResidue?: boolean | {
|
|
650
|
+
marker?: string;
|
|
651
|
+
};
|
|
652
|
+
}): TermlessTerm;
|
|
653
|
+
/**
|
|
654
|
+
* Normalize frame output for comparison.
|
|
655
|
+
* - Strips ANSI codes
|
|
656
|
+
* - Trims trailing whitespace from lines
|
|
657
|
+
* - Removes empty trailing lines
|
|
658
|
+
*/
|
|
659
|
+
declare function normalizeFrame(frame: string): string;
|
|
660
|
+
/**
|
|
661
|
+
* Wait for a condition to be true, polling at intervals.
|
|
662
|
+
* Useful for waiting for async state updates.
|
|
663
|
+
*/
|
|
664
|
+
declare function waitFor(condition: () => boolean, {
|
|
665
|
+
timeout,
|
|
666
|
+
interval
|
|
667
|
+
}?: {
|
|
668
|
+
timeout?: number | undefined;
|
|
669
|
+
interval?: number | undefined;
|
|
670
|
+
}): Promise<void>;
|
|
671
|
+
//#endregion
|
|
672
|
+
export { type App, type AutoLocator, type BoundTerm, type BufferMismatch, type CLSReport, CLS_STRICT_MIN_TIER, CLS_STRICT_SLUG, CODE_TO_KEY, type CellChange, type DebugTreeOptions, type FilterOptions, type FrameRecordable, type FrameRecording, type LayoutShift, type PerRenderOptions, type ReasonClassifier, type Rect, type ReflowReason, type RenderOptions, type Store, type StoreOptions, type TerminalBuffer, TermlessClipboard, TermlessMouse, TermlessMouseCellSize, TermlessMouseCoordinateMode, TermlessMouseModifiers, TermlessMouseOptions, TermlessOutput, TermlessPoint, TermlessReflowResidue, TermlessTerm, TermlessTrackpadFlickDebugLogOptions, TermlessTrackpadFlickGroup, TermlessTrackpadFlickOptions, TermlessTrackpadFlickPacket, TermlessTrackpadFlickProfile, TermlessTrackpadFlickResult, TermlessWheelDirection, TermlessWheelOptions, type TestCellSnapshot, type TransientPredicate, UnexpectedLayoutShiftError, bufferToHTML, bufferToStyledText, bufferToText, compareBuffers, createAutoLocator, createRenderer, createStore, createTermless, debugTree, diagnosticScheme, diagnosticTheme, ensureEngine, formatMismatch, formatSelectableCells, getActiveRenderCount, getActiveTermlessCount, isClsStrictEnabled, keyToAnsi, keyToKittyAnsi, normalizeFrame, parseTermlessTrackpadFlickProfileFromDebugLog, readCellRow, readCellSnapshot, recordFrames, render, run, stripAnsi, waitFor };
|
|
673
|
+
//# sourceMappingURL=test.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.mts","names":[],"sources":["../packages/ag-term/src/strict-cls.ts","../packages/test/src/debug.ts","../packages/test/src/diagnostic-theme.ts","../packages/test/src/compare-buffers.ts","../packages/test/src/cell-inspector.ts","../packages/test/src/frame-recorder.ts","../packages/ag-term/src/renderer.ts","../packages/test/src/index.tsx"],"mappings":"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"}
|