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.
Files changed (224) hide show
  1. package/README.md +1 -1
  2. package/dist/{Text-Lq0dmj8-.mjs → Text-Ci6UCSTL.mjs} +46 -48
  3. package/dist/Text-Ci6UCSTL.mjs.map +1 -0
  4. package/dist/{render-string-DkQacASz.mjs → ag-q9lRlKlt.mjs} +5322 -4259
  5. package/dist/ag-q9lRlKlt.mjs.map +1 -0
  6. package/dist/{animation-ZMN2_XKv.mjs → animation-CZ4x2R7C.mjs} +1 -1
  7. package/dist/{animation-ZMN2_XKv.mjs.map → animation-CZ4x2R7C.mjs.map} +1 -1
  8. package/dist/{ansi-D1KQMAbf.mjs → ansi-CLmIMnop.mjs} +1 -1
  9. package/dist/{ansi-D1KQMAbf.mjs.map → ansi-CLmIMnop.mjs.map} +1 -1
  10. package/dist/{ansi-2Xn0yatP.d.mts → ansi-zmNzgkPB.d.mts} +1 -1
  11. package/dist/{ansi-2Xn0yatP.d.mts.map → ansi-zmNzgkPB.d.mts.map} +1 -1
  12. package/dist/{backend-B-WYLUib.mjs → backend-DSiSIc-h.mjs} +2 -2
  13. package/dist/{backend-B-WYLUib.mjs.map → backend-DSiSIc-h.mjs.map} +1 -1
  14. package/dist/chain-bridge-CkYcMxlq.mjs +4149 -0
  15. package/dist/chain-bridge-CkYcMxlq.mjs.map +1 -0
  16. package/dist/{chunk-BSw8zbkd.mjs → chunk-BEJ448es.mjs} +1 -3
  17. package/dist/cli-VNqUKlXw.mjs +4 -0
  18. package/dist/{context-BU5LkkIy.mjs → context-CEhuD1R_.mjs} +1 -1
  19. package/dist/{context-BU5LkkIy.mjs.map → context-CEhuD1R_.mjs.map} +1 -1
  20. package/dist/devtools-BF4IMumr.mjs +2 -0
  21. package/dist/{devtools-DcQjgyjL.mjs → devtools-td2AjFwc.mjs} +5 -5
  22. package/dist/{devtools-DcQjgyjL.mjs.map → devtools-td2AjFwc.mjs.map} +1 -1
  23. package/dist/{easing-BI-ASGMO.d.mts → easing-C5MrdO7V.d.mts} +1 -1
  24. package/dist/{easing-BI-ASGMO.d.mts.map → easing-C5MrdO7V.d.mts.map} +1 -1
  25. package/dist/{eta-CJlGH06n.mjs → eta-BwYWEjfS.mjs} +1 -1
  26. package/dist/{eta-CJlGH06n.mjs.map → eta-BwYWEjfS.mjs.map} +1 -1
  27. package/dist/{flexily-zero-adapter-C4lW_Ov5.mjs → flexily-zero-adapter-DktX3HsX.mjs} +1 -1
  28. package/dist/{flexily-zero-adapter-C3Vj0fPt.mjs → flexily-zero-adapter-VoBGHG14.mjs} +1 -1
  29. package/dist/{flexily-zero-adapter-C3Vj0fPt.mjs.map → flexily-zero-adapter-VoBGHG14.mjs.map} +1 -1
  30. package/dist/hit-registry-D_nxOivS.d.mts +71 -0
  31. package/dist/hit-registry-D_nxOivS.d.mts.map +1 -0
  32. package/dist/{UPNG-DosRPdF4.mjs → image-CIF75xMr.mjs} +891 -6
  33. package/dist/image-CIF75xMr.mjs.map +1 -0
  34. package/dist/{index-CSQf13CI.d.mts → index-377zdPLP.d.mts} +35 -12
  35. package/dist/index-377zdPLP.d.mts.map +1 -0
  36. package/dist/{index-Cl9KKjQ_.d.mts → index-BcSr0RAQ.d.mts} +8670 -10659
  37. package/dist/index-BcSr0RAQ.d.mts.map +1 -0
  38. package/dist/{index-XbNrPhWl.d.mts → index-DLnpxDAm.d.mts} +2 -2
  39. package/dist/{index-XbNrPhWl.d.mts.map → index-DLnpxDAm.d.mts.map} +1 -1
  40. package/dist/{index-BUMxS65f.d.mts → index-DlNmckTq.d.mts} +2 -2
  41. package/dist/{index-BUMxS65f.d.mts.map → index-DlNmckTq.d.mts.map} +1 -1
  42. package/dist/index.d.mts +12 -8
  43. package/dist/index.d.mts.map +1 -1
  44. package/dist/index.mjs +18 -15
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/{layout-engine-C2px0RJE.mjs → layout-engine-BgR58vL0.mjs} +3 -3
  47. package/dist/{layout-engine-C2px0RJE.mjs.map → layout-engine-BgR58vL0.mjs.map} +1 -1
  48. package/dist/{layout-engine-C07LEXWT.mjs → layout-engine-DNjTha8f.mjs} +1 -1
  49. package/dist/{layout-signals-Cnw6xk8Q.mjs → layout-signals-CGYbHmxy.mjs} +146 -23
  50. package/dist/layout-signals-CGYbHmxy.mjs.map +1 -0
  51. package/dist/{bound-term-0sPrrzH1.d.mts → mouse-events-B2z5tbsL.d.mts} +780 -379
  52. package/dist/mouse-events-B2z5tbsL.d.mts.map +1 -0
  53. package/dist/{mouse-events-Dki3ISIp.mjs → mouse-events-WQ2h-uqG.mjs} +45 -10
  54. package/dist/mouse-events-WQ2h-uqG.mjs.map +1 -0
  55. package/dist/{multi-progress-DHZ2xUT2.d.mts → multi-progress-BaEFfHKP.d.mts} +2 -2
  56. package/dist/{multi-progress-DHZ2xUT2.d.mts.map → multi-progress-BaEFfHKP.d.mts.map} +1 -1
  57. package/dist/{multi-progress-CIRjrzma.mjs → multi-progress-zCWHEm9P.mjs} +3 -3
  58. package/dist/{multi-progress-CIRjrzma.mjs.map → multi-progress-zCWHEm9P.mjs.map} +1 -1
  59. package/dist/{node-CjM5Rt-M.mjs → node-CJ3J_rW-.mjs} +1 -1
  60. package/dist/{node-CjM5Rt-M.mjs.map → node-CJ3J_rW-.mjs.map} +1 -1
  61. package/dist/{progress-DB_Xo071.mjs → progress-6vJ7nxUg.mjs} +4 -4
  62. package/dist/{progress-DB_Xo071.mjs.map → progress-6vJ7nxUg.mjs.map} +1 -1
  63. package/dist/{progress-bar-oJwq22CR.mjs → progress-bar-BlFNsZL8.mjs} +4 -4
  64. package/dist/{progress-bar-oJwq22CR.mjs.map → progress-bar-BlFNsZL8.mjs.map} +1 -1
  65. package/dist/{reconciler-DldIJB93.mjs → reconciler--_-biN23.mjs} +190 -134
  66. package/dist/reconciler--_-biN23.mjs.map +1 -0
  67. package/dist/{render-string-BcoCpjCB.mjs → render-string-DaghHpLN.mjs} +1 -1
  68. package/dist/render-string-DtHZP0cU.mjs +215 -0
  69. package/dist/render-string-DtHZP0cU.mjs.map +1 -0
  70. package/dist/runtime.d.mts +4 -3
  71. package/dist/runtime.mjs +4 -3
  72. package/dist/schemes-DWQPxXAi.mjs +2516 -0
  73. package/dist/{schemes-JjNp4aSl.mjs.map → schemes-DWQPxXAi.mjs.map} +1 -1
  74. package/dist/{spinner-D9lrHr8s.mjs → spinner-B50hILqx.mjs} +19 -4
  75. package/dist/{spinner-D9lrHr8s.mjs.map → spinner-B50hILqx.mjs.map} +1 -1
  76. package/dist/{spinner-CZINHpkV.d.mts → spinner-DN10UfF0.d.mts} +2 -2
  77. package/dist/{spinner-CZINHpkV.d.mts.map → spinner-DN10UfF0.d.mts.map} +1 -1
  78. package/dist/{src-BNTToU7l.mjs → src-B8lf1kiR.mjs} +1507 -1166
  79. package/dist/src-B8lf1kiR.mjs.map +1 -0
  80. package/dist/{src-5w9QR6_8.mjs → src-BOLdi3WG.mjs} +105 -237
  81. package/dist/src-BOLdi3WG.mjs.map +1 -0
  82. package/dist/{src-BR4xNwdG.mjs → src-BXeTHHlL.mjs} +20240 -25437
  83. package/dist/src-BXeTHHlL.mjs.map +1 -0
  84. package/dist/{src-DKp-_OFG.mjs → src-BqeBFB3X.mjs} +90 -47
  85. package/dist/src-BqeBFB3X.mjs.map +1 -0
  86. package/dist/src-DbqcSrhy.mjs +3901 -0
  87. package/dist/src-DbqcSrhy.mjs.map +1 -0
  88. package/dist/{steps-Bp2uNqnn.d.mts → steps-B2kBmFpb.d.mts} +1 -1
  89. package/dist/{steps-Bp2uNqnn.d.mts.map → steps-B2kBmFpb.d.mts.map} +1 -1
  90. package/dist/{svg-Cz0UXcDj.mjs → svg-NmV9dgB9.mjs} +1 -1
  91. package/dist/{svg-Cz0UXcDj.mjs.map → svg-NmV9dgB9.mjs.map} +1 -1
  92. package/dist/{svg-g1D6ErwR.d.mts → svg-VUr78l5d.d.mts} +1 -1
  93. package/dist/{svg-g1D6ErwR.d.mts.map → svg-VUr78l5d.d.mts.map} +1 -1
  94. package/dist/term.d.mts +2 -2
  95. package/dist/term.mjs +3 -8
  96. package/dist/test.d.mts +673 -0
  97. package/dist/test.d.mts.map +1 -0
  98. package/dist/test.mjs +2829 -0
  99. package/dist/test.mjs.map +1 -0
  100. package/dist/theme.d.mts +2 -2
  101. package/dist/theme.d.mts.map +1 -1
  102. package/dist/theme.mjs +3 -8
  103. package/dist/{types-kt_fKR37.d.mts → types-D_E0FbqA.d.mts} +1 -1
  104. package/dist/{types-kt_fKR37.d.mts.map → types-D_E0FbqA.d.mts.map} +1 -1
  105. package/dist/ui/animation.d.mts +2 -2
  106. package/dist/ui/animation.mjs +1 -1
  107. package/dist/ui/ansi.d.mts +1 -1
  108. package/dist/ui/ansi.mjs +1 -1
  109. package/dist/ui/cli.d.mts +3 -3
  110. package/dist/ui/cli.mjs +5 -5
  111. package/dist/ui/image.d.mts +1 -1
  112. package/dist/ui/image.mjs +1 -1
  113. package/dist/ui/progress.d.mts +4 -4
  114. package/dist/ui/progress.mjs +4 -4
  115. package/dist/ui/react.d.mts +1 -1
  116. package/dist/ui/react.mjs +2 -2
  117. package/dist/ui/recording-chrome-react.d.mts +1 -1
  118. package/dist/ui/recording-chrome-react.mjs +2 -2
  119. package/dist/ui/recording-chrome.d.mts +1 -1
  120. package/dist/ui/recording-chrome.mjs +1 -1
  121. package/dist/ui/utils.mjs +1 -1
  122. package/dist/ui/wrappers.d.mts +2 -2
  123. package/dist/ui/wrappers.mjs +1 -1
  124. package/dist/ui.d.mts +6 -6
  125. package/dist/ui.mjs +7 -7
  126. package/dist/unicode-CxyxVGmB.mjs +11077 -0
  127. package/dist/unicode-CxyxVGmB.mjs.map +1 -0
  128. package/dist/{useLatest-DRDDVwjh.d.mts → useLatest-UOvWy0ZW.d.mts} +2 -2
  129. package/dist/{useLatest-DRDDVwjh.d.mts.map → useLatest-UOvWy0ZW.d.mts.map} +1 -1
  130. package/dist/useLayout-D5cE8OCI.mjs +424 -0
  131. package/dist/useLayout-D5cE8OCI.mjs.map +1 -0
  132. package/dist/{with-text-input-YeohVLeo.d.mts → with-text-input-DLoSCBrm.d.mts} +3 -3
  133. package/dist/{with-text-input-YeohVLeo.d.mts.map → with-text-input-DLoSCBrm.d.mts.map} +1 -1
  134. package/dist/wrap-measurer-registration-IV2HtcCd.d.mts +3106 -0
  135. package/dist/wrap-measurer-registration-IV2HtcCd.d.mts.map +1 -0
  136. package/dist/{wrapper-C70ATkVv.mjs → wrapper-CD29afOs.mjs} +59 -17
  137. package/dist/wrapper-CD29afOs.mjs.map +1 -0
  138. package/dist/{wrappers-BCUYITrY.mjs → wrappers-CInBJm44.mjs} +18 -8
  139. package/dist/wrappers-CInBJm44.mjs.map +1 -0
  140. package/dist/{yoga-adapter-BnZX1PAY.mjs → yoga-adapter-9uab5Qn-.mjs} +2 -2
  141. package/dist/{yoga-adapter-BnZX1PAY.mjs.map → yoga-adapter-9uab5Qn-.mjs.map} +1 -1
  142. package/dist/yoga-adapter-yqTl1aXK.mjs +2 -0
  143. package/package.json +59 -14
  144. package/dist/Text-Lq0dmj8-.mjs.map +0 -1
  145. package/dist/UPNG-Bo33r8rA.mjs +0 -3
  146. package/dist/UPNG-DosRPdF4.mjs.map +0 -1
  147. package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs +0 -6
  148. package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs.map +0 -1
  149. package/dist/ansi-yC4RyBNY.mjs +0 -22441
  150. package/dist/ansi-yC4RyBNY.mjs.map +0 -1
  151. package/dist/apng-CR08rIaH.mjs +0 -58
  152. package/dist/apng-CR08rIaH.mjs.map +0 -1
  153. package/dist/apng-DaHfVaVI.mjs +0 -3
  154. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  155. package/dist/assets/skia.darwin-arm64-DQs5sT6N.node +0 -0
  156. package/dist/backends-CUtan80W.mjs +0 -3
  157. package/dist/backends-DIVYzKqd.mjs +0 -1083
  158. package/dist/backends-DIVYzKqd.mjs.map +0 -1
  159. package/dist/bound-term-0sPrrzH1.d.mts.map +0 -1
  160. package/dist/canvas-1v7dPT-_.mjs +0 -3
  161. package/dist/canvas-CSuPOMNt.mjs +0 -1442
  162. package/dist/canvas-CSuPOMNt.mjs.map +0 -1
  163. package/dist/cli-dvo0r2fs.mjs +0 -4
  164. package/dist/compare-CQodSH4G.mjs +0 -376
  165. package/dist/compare-CQodSH4G.mjs.map +0 -1
  166. package/dist/compare-DHlcxEYA.mjs +0 -3
  167. package/dist/devtools-CJdt5H0X.mjs +0 -2
  168. package/dist/fonts-BFmhXDv7.mjs +0 -88
  169. package/dist/fonts-BFmhXDv7.mjs.map +0 -1
  170. package/dist/gif-C_AjaT9d.mjs +0 -188
  171. package/dist/gif-C_AjaT9d.mjs.map +0 -1
  172. package/dist/gif-DaC4XrxA.mjs +0 -3
  173. package/dist/gifenc-BOUT-KFB.mjs +0 -730
  174. package/dist/gifenc-BOUT-KFB.mjs.map +0 -1
  175. package/dist/image-C2Birh2x.mjs +0 -1252
  176. package/dist/image-C2Birh2x.mjs.map +0 -1
  177. package/dist/index-CSQf13CI.d.mts.map +0 -1
  178. package/dist/index-Cl9KKjQ_.d.mts.map +0 -1
  179. package/dist/key-mapping-CS-YD_cD.mjs +0 -132
  180. package/dist/key-mapping-CS-YD_cD.mjs.map +0 -1
  181. package/dist/key-mapping-Yn-Jgrij.mjs +0 -3
  182. package/dist/layout-signals-Cnw6xk8Q.mjs.map +0 -1
  183. package/dist/mouse-events-Dki3ISIp.mjs.map +0 -1
  184. package/dist/playwright-D5YiZcNS.mjs +0 -76397
  185. package/dist/playwright-D5YiZcNS.mjs.map +0 -1
  186. package/dist/png-codec-Dp84742B.mjs +0 -36
  187. package/dist/png-codec-Dp84742B.mjs.map +0 -1
  188. package/dist/png-codec-QwOtJ8Zs.mjs +0 -3
  189. package/dist/rasterizer-BRXrDdWx.mjs +0 -3
  190. package/dist/rasterizer-CpEhJvdR.mjs +0 -296
  191. package/dist/rasterizer-CpEhJvdR.mjs.map +0 -1
  192. package/dist/reconciler-DldIJB93.mjs.map +0 -1
  193. package/dist/render-string-DkQacASz.mjs.map +0 -1
  194. package/dist/resvg-js-DkOndZI3.mjs +0 -203
  195. package/dist/resvg-js-DkOndZI3.mjs.map +0 -1
  196. package/dist/schemes-JjNp4aSl.mjs +0 -2611
  197. package/dist/src-5w9QR6_8.mjs.map +0 -1
  198. package/dist/src-BNTToU7l.mjs.map +0 -1
  199. package/dist/src-BR4xNwdG.mjs.map +0 -1
  200. package/dist/src-DKp-_OFG.mjs.map +0 -1
  201. package/dist/src-bt8wSrfJ.mjs +0 -258
  202. package/dist/src-bt8wSrfJ.mjs.map +0 -1
  203. package/dist/src-e33Y6kNJ.mjs +0 -3
  204. package/dist/src-iDwu25UD.mjs +0 -1814
  205. package/dist/src-iDwu25UD.mjs.map +0 -1
  206. package/dist/svg-15lZZzxq.mjs +0 -486
  207. package/dist/svg-15lZZzxq.mjs.map +0 -1
  208. package/dist/svg-DY72a4HK.mjs +0 -3
  209. package/dist/term.mjs.map +0 -1
  210. package/dist/theme.mjs.map +0 -1
  211. package/dist/ui/display.d.mts +0 -35
  212. package/dist/ui/display.d.mts.map +0 -1
  213. package/dist/ui/display.mjs +0 -123
  214. package/dist/ui/display.mjs.map +0 -1
  215. package/dist/ui/input.d.mts +0 -184
  216. package/dist/ui/input.d.mts.map +0 -1
  217. package/dist/ui/input.mjs +0 -285
  218. package/dist/ui/input.mjs.map +0 -1
  219. package/dist/wrapper-C70ATkVv.mjs.map +0 -1
  220. package/dist/wrappers-BCUYITrY.mjs.map +0 -1
  221. package/dist/yoga-adapter-DxgsQ_gg.mjs +0 -2
  222. package/dist/zipBundle-3nqeDRtm.mjs +0 -3
  223. package/dist/zipBundle-VNAYFmqJ.mjs +0 -2003
  224. package/dist/zipBundle-VNAYFmqJ.mjs.map +0 -1
@@ -0,0 +1,3106 @@
1
+ import { D as enableKittyKeyboard$1, E as disableMouse$1, F as TerminalCaps, O as enableMouse$1, T as disableKittyKeyboard$1, j as ColorLevel } from "./index-377zdPLP.mjs";
2
+ import { Ct as Decoration, Ht as LayoutNode$1, Q as UnderlineStyle, S as Term, Tt as EventSource, X as Style, Z as TerminalBuffer, _ as BoundTerm, gt as AgNodeType, ht as AgNode, jt as Rect, nt as FrameCell, ut as FocusManager, wt as Event, xt as CursorShape$1 } from "./mouse-events-B2z5tbsL.mjs";
3
+ import React, { ReactElement, ReactNode } from "react";
4
+
5
+ //#region packages/ag-term/src/unicode.d.ts
6
+ /**
7
+ * Run a function with a specific measurer as the active scope.
8
+ * Module-level convenience functions (graphemeWidth, displayWidth, etc.)
9
+ * will use this measurer instead of the lazy default for the duration.
10
+ */
11
+ declare function runWithMeasurer<T>(measurer: Measurer, fn: () => T): T;
12
+ /**
13
+ * Check if text sizing mode is currently enabled.
14
+ * Returns the default (false) since globals have been removed.
15
+ * Use measurer.textSizing for scoped queries.
16
+ */
17
+ declare function isTextSizingEnabled(): boolean;
18
+ /**
19
+ * Width measurement functions scoped to specific terminal capabilities.
20
+ * Created by createMeasurer() from TerminalCaps.
21
+ */
22
+ interface Measurer {
23
+ readonly maybeWideEmojis: boolean;
24
+ readonly textSizing: boolean;
25
+ /** Height of one line in measurement units. Terminal: 1 (one cell row). Canvas pixel: e.g. 20. */
26
+ readonly lineHeight: number;
27
+ displayWidth(text: string): number;
28
+ displayWidthAnsi(text: string): number;
29
+ graphemeWidth(grapheme: string): number;
30
+ wrapText(text: string, width: number, trim?: boolean, hard?: boolean, truncateAtomicOverflow?: boolean): string[];
31
+ sliceByWidth(text: string, maxWidth: number): string;
32
+ sliceByWidthFromEnd(text: string, maxWidth: number): string;
33
+ }
34
+ /**
35
+ * Create a width measurer scoped to terminal capabilities.
36
+ * Each measurer has its own caches (no shared global state).
37
+ */
38
+ declare function createMeasurer(caps?: {
39
+ maybeWideEmojis?: boolean;
40
+ textSizing?: boolean;
41
+ }): Measurer;
42
+ /**
43
+ * Split a string into grapheme clusters.
44
+ * Each grapheme is a user-perceived character that may consist of
45
+ * multiple Unicode code points.
46
+ *
47
+ * Examples:
48
+ * - "cafe\u0301" (café with combining accent) -> ["c", "a", "f", "e\u0301"]
49
+ * - "👨‍👩‍👧" (family emoji) -> ["👨‍👩‍👧"]
50
+ * - "한국어" -> ["한", "국", "어"]
51
+ */
52
+ declare function splitGraphemes(text: string): string[];
53
+ /**
54
+ * Count the number of graphemes in a string.
55
+ */
56
+ declare function graphemeCount(text: string): number;
57
+ /**
58
+ * Append VS16 (U+FE0F) to emoji characters that have default text presentation.
59
+ *
60
+ * Use this to normalize icon characters for consistent terminal rendering.
61
+ * Characters that already have emoji presentation or VS16 are returned unchanged.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * ensureEmojiPresentation('⚠') // '⚠\uFE0F' (⚠️)
66
+ * ensureEmojiPresentation('☑') // '☑\uFE0F' (☑️)
67
+ * ensureEmojiPresentation('☐') // '☐' (unchanged, not an emoji)
68
+ * ensureEmojiPresentation('📁') // '📁' (unchanged, already emoji presentation)
69
+ * ```
70
+ */
71
+ declare function ensureEmojiPresentation(char: string): string;
72
+ /**
73
+ * Get the display width of a string (number of terminal columns).
74
+ * Uses string-width which handles:
75
+ * - Wide characters (CJK) -> 2 columns
76
+ * - Regular ASCII -> 1 column
77
+ * - Zero-width characters (combining, ZWJ) -> 0 columns
78
+ * - Emoji -> varies (1 or 2)
79
+ * - ANSI escape sequences -> 0 columns (stripped)
80
+ *
81
+ * Corrects string-width for text-presentation emoji characters
82
+ * (e.g., ⚠ U+26A0) that terminals render as 2 columns wide.
83
+ *
84
+ * Results are cached for performance.
85
+ */
86
+ declare function displayWidth(text: string): number;
87
+ /**
88
+ * Get the display width of a single grapheme.
89
+ *
90
+ * Overrides string-width for characters that are Extended_Pictographic with
91
+ * default text presentation. These characters (e.g., ⚠ U+26A0, ☑ U+2611)
92
+ * are reported as width 1 by string-width (per Unicode EAW tables), but most
93
+ * modern terminals render them as 2 columns wide using emoji glyphs.
94
+ *
95
+ * The mismatch causes text after these characters to be placed at the wrong
96
+ * column, leading to truncation or overlap.
97
+ */
98
+ declare function graphemeWidth(grapheme: string): number;
99
+ /**
100
+ * Check if a grapheme is a wide character (takes 2 columns).
101
+ */
102
+ declare function isWideGrapheme(grapheme: string): boolean;
103
+ /**
104
+ * Check if a grapheme is zero-width (combining character, ZWJ, etc.).
105
+ */
106
+ declare function isZeroWidthGrapheme(grapheme: string): boolean;
107
+ /**
108
+ * Truncate a string to fit within a given display width.
109
+ * Handles wide characters and ANSI escape sequences (including OSC 8 hyperlinks) correctly.
110
+ *
111
+ * @param text - The text to truncate (may contain ANSI escape sequences)
112
+ * @param maxWidth - Maximum display width
113
+ * @param ellipsis - Ellipsis to append if truncated (default: "...")
114
+ * @returns Truncated string
115
+ */
116
+ declare function truncateText(text: string, maxWidth: number, ellipsis?: string): string;
117
+ /**
118
+ * Pad a string to a given display width.
119
+ *
120
+ * @param text - The text to pad
121
+ * @param width - Target display width
122
+ * @param align - Alignment: 'left', 'right', or 'center'
123
+ * @param padChar - Character to use for padding (default: space)
124
+ * @returns Padded string
125
+ */
126
+ declare function padText(text: string, width: number, align?: "left" | "right" | "center", padChar?: string): string;
127
+ /**
128
+ * Constrain text to width and height limits.
129
+ * Combines wrapping and truncation to fit text in a box.
130
+ *
131
+ * @param text - Text to constrain (may contain ANSI codes)
132
+ * @param width - Maximum display width per line
133
+ * @param maxLines - Maximum number of lines
134
+ * @param pad - If true, pad lines to full width
135
+ * @param ellipsis - Custom ellipsis character (default: "…")
136
+ * @returns Object with lines array and truncated flag
137
+ */
138
+ declare function constrainText(text: string, width: number, maxLines: number, pad?: boolean, ellipsis?: string): {
139
+ lines: string[];
140
+ truncated: boolean;
141
+ };
142
+ /**
143
+ * Wrap text to fit within a given width.
144
+ *
145
+ * Implements word-boundary wrapping:
146
+ * 1. Breaks at word boundaries (spaces, hyphens) when possible
147
+ * 2. Falls back to character wrap only when necessary (very long words)
148
+ * 3. Handles CJK text properly (can break anywhere since CJK has no word spaces)
149
+ * 4. Preserves intentional line breaks
150
+ *
151
+ * @param text - The text to wrap (may contain ANSI escape sequences)
152
+ * @param width - Maximum display width per line
153
+ * @param preserveNewlines - Whether to preserve existing newlines
154
+ * @param trim - Trim trailing spaces on broken lines and skip leading spaces on continuation lines (useful for rendering)
155
+ * @param truncateAtomicOverflow - When true, an unbreakable token wider than
156
+ * `width` (no soft-break separator) ends with a Unicode `…` ellipsis on
157
+ * the offending line and the rest of the token is dropped, instead of
158
+ * character-wrapping. Implements the `wrap="wrap-truncate"` mode —
159
+ * CSS-equivalent `overflow-wrap: break-word` + `text-overflow: ellipsis`.
160
+ * Default `false` preserves existing character-wrap fallback (`wrap="wrap"`).
161
+ * @returns Array of wrapped lines
162
+ */
163
+ declare function wrapText(text: string, width: number, preserveNewlines?: boolean, trim?: boolean, truncateAtomicOverflow?: boolean): string[];
164
+ /**
165
+ * Slice text by display width (from start).
166
+ * Returns the first `maxWidth` columns of text.
167
+ * Uses the default measurer for width calculations.
168
+ * Handles both ANSI-styled and plain text.
169
+ *
170
+ * @param text - The text to slice
171
+ * @param maxWidth - Maximum display width to keep from the start
172
+ * @returns Sliced string from the start
173
+ */
174
+ declare function sliceByWidth(text: string, maxWidth: number): string;
175
+ /**
176
+ * Slice a string by display width range.
177
+ * Like string.slice() but works with display columns.
178
+ *
179
+ * @param text - The text to slice
180
+ * @param start - Start display column (inclusive)
181
+ * @param end - End display column (exclusive)
182
+ * @returns Sliced string
183
+ */
184
+ declare function sliceByWidthRange(text: string, start: number, end?: number): string;
185
+ /**
186
+ * Slice text by display width from the end.
187
+ * Returns the last `maxWidth` columns of text.
188
+ * Uses the default measurer for width calculations.
189
+ *
190
+ * @param text - The text to slice
191
+ * @param maxWidth - Maximum display width to keep from the end
192
+ * @returns Sliced string from the end
193
+ */
194
+ declare function sliceByWidthFromEnd(text: string, maxWidth: number): string;
195
+ /**
196
+ * Write styled text to a terminal buffer.
197
+ *
198
+ * Handles:
199
+ * - Multi-byte graphemes (emoji, combining characters)
200
+ * - Wide characters (CJK) that take 2 cells
201
+ * - Zero-width characters (appended to previous cell)
202
+ *
203
+ * @param buffer - The buffer to write to
204
+ * @param x - Starting column
205
+ * @param y - Row
206
+ * @param text - Text to write
207
+ * @param style - Style to apply
208
+ * @returns The ending column (x + display_width)
209
+ */
210
+ declare function writeTextToBuffer(buffer: TerminalBuffer, x: number, y: number, text: string, style?: Style): number;
211
+ /**
212
+ * Write styled text to a buffer with automatic truncation.
213
+ *
214
+ * @param buffer - The buffer to write to
215
+ * @param x - Starting column
216
+ * @param y - Row
217
+ * @param text - Text to write
218
+ * @param maxWidth - Maximum width (truncate if exceeded)
219
+ * @param style - Style to apply
220
+ * @param ellipsis - Ellipsis for truncated text
221
+ */
222
+ declare function writeTextTruncated(buffer: TerminalBuffer, x: number, y: number, text: string, maxWidth: number, style?: Style, ellipsis?: string): void;
223
+ /**
224
+ * Write multiple lines of styled text to a buffer.
225
+ *
226
+ * @param buffer - The buffer to write to
227
+ * @param x - Starting column
228
+ * @param y - Starting row
229
+ * @param lines - Lines to write
230
+ * @param style - Style to apply
231
+ */
232
+ declare function writeLinesToBuffer(buffer: TerminalBuffer, x: number, y: number, lines: string[], style?: Style): void;
233
+ /**
234
+ * Strip all ANSI escape codes from a string.
235
+ *
236
+ * Handles:
237
+ * - CSI sequences (cursor movement, colors, SGR, etc.)
238
+ * - OSC sequences (window titles, hyperlinks)
239
+ * - Single-character escape sequences
240
+ * - Character set selection
241
+ */
242
+ declare function stripAnsi(text: string): string;
243
+ /**
244
+ * Get display width of text with ANSI sequences.
245
+ * ANSI sequences don't contribute to display width.
246
+ */
247
+ declare function displayWidthAnsi(text: string): number;
248
+ /**
249
+ * Truncate text that may contain ANSI sequences.
250
+ * Preserves ANSI codes while truncating visible characters.
251
+ *
252
+ * Note: This is a simplified implementation that strips ANSI before
253
+ * truncation. For proper ANSI-aware truncation, consider using
254
+ * slice-ansi or similar library.
255
+ */
256
+ declare function truncateAnsi(text: string, maxWidth: number, ellipsis?: string): string;
257
+ /** Styled text segment with associated ANSI colors/attributes */
258
+ interface StyledSegment {
259
+ text: string;
260
+ fg?: number | null;
261
+ bg?: number | null;
262
+ /**
263
+ * Underline color (SGR 58).
264
+ * Same format as fg/bg: packed RGB with 0x1000000 marker, or 256-color index.
265
+ */
266
+ underlineColor?: number | null;
267
+ bold?: boolean;
268
+ dim?: boolean;
269
+ italic?: boolean;
270
+ underline?: boolean;
271
+ /**
272
+ * Underline style variant (SGR 4:x).
273
+ * Uses UnderlineStyle from buffer.ts.
274
+ */
275
+ underlineStyle?: UnderlineStyle;
276
+ inverse?: boolean;
277
+ /** Strikethrough (SGR 9 on, SGR 29 off). */
278
+ strikethrough?: boolean;
279
+ /** Overline (SGR 53 on, SGR 55 off). */
280
+ overline?: boolean;
281
+ bgOverride?: boolean;
282
+ /**
283
+ * OSC 8 hyperlink URL.
284
+ * Set when the segment is inside an OSC 8 hyperlink sequence.
285
+ */
286
+ hyperlink?: string;
287
+ /**
288
+ * True when the foreground color was specified using colon-separated SGR
289
+ * (e.g., `38:2::255:100:0m` instead of `38;2;255;100;0m`).
290
+ * Used to preserve the original format in round-trip output.
291
+ */
292
+ colonFg?: boolean;
293
+ /**
294
+ * True when the background color was specified using colon-separated SGR.
295
+ */
296
+ colonBg?: boolean;
297
+ }
298
+ /**
299
+ * Parse text with ANSI escape sequences into styled segments.
300
+ * Handles basic SGR (Select Graphic Rendition) codes including:
301
+ * - Standard colors (30-37, 40-47, 90-97, 100-107)
302
+ * - Extended colors (38;5;N, 48;5;N for 256-color, 38;2;r;g;b, 48;2;r;g;b for RGB)
303
+ * - Underline styles (4:x where x = 0-5)
304
+ * - Underline color (58;5;N for 256-color, 58;2;r;g;b for RGB)
305
+ */
306
+ declare function parseAnsiText(text: string): StyledSegment[];
307
+ /**
308
+ * Check if text contains ANSI escape sequences (SGR or OSC).
309
+ * Detects both ESC-based (7-bit) and C1 (8-bit) forms:
310
+ * - ESC [ params final (CSI)
311
+ * - ESC ] (OSC)
312
+ * - U+009B params final (C1 CSI)
313
+ * - U+009D (C1 OSC)
314
+ */
315
+ declare function hasAnsi(text: string): boolean;
316
+ /**
317
+ * Measure the dimensions of multi-line text.
318
+ *
319
+ * @param text - Text to measure (may contain newlines)
320
+ * @returns { width, height } in display columns and rows
321
+ */
322
+ declare function measureText(text: string): {
323
+ width: number;
324
+ height: number;
325
+ };
326
+ /**
327
+ * Check if a string contains any wide characters.
328
+ */
329
+ declare function hasWideCharacters(text: string): boolean;
330
+ /**
331
+ * Check if a string contains any combining/zero-width characters.
332
+ */
333
+ declare function hasZeroWidthCharacters(text: string): boolean;
334
+ /**
335
+ * Normalize string for consistent handling.
336
+ * Applies Unicode NFC normalization.
337
+ */
338
+ declare function normalizeText(text: string): string;
339
+ /**
340
+ * Get the first code point of a string.
341
+ */
342
+ declare function getFirstCodePoint(str: string): number;
343
+ /**
344
+ * Check if a grapheme is likely an emoji.
345
+ * Note: This is a heuristic, not comprehensive.
346
+ */
347
+ declare function isLikelyEmoji(grapheme: string): boolean;
348
+ /**
349
+ * Check if a grapheme is a CJK character.
350
+ */
351
+ declare function isCJK(grapheme: string): boolean;
352
+ //#endregion
353
+ //#region packages/ag-term/src/clipboard.d.ts
354
+ /**
355
+ * Clipboard Backend Abstraction
356
+ *
357
+ * Pluggable clipboard system with support for multiple backends.
358
+ * The default backend uses OSC 52 for terminal clipboard access.
359
+ *
360
+ * Architecture:
361
+ * - ClipboardBackend: interface for clipboard read/write
362
+ * - ClipboardData: multi-format clipboard content (text, markdown, html, internal)
363
+ * - createOsc52Backend: OSC 52 terminal clipboard (default)
364
+ * - createInternalClipboardBackend: in-memory store for rich app-internal paste
365
+ * - createCompositeClipboard: fan-out writes to multiple backends
366
+ *
367
+ * OSC 52 Protocol:
368
+ * - Copy: ESC ] 52 ; c ; <base64> BEL
369
+ * - Query: ESC ] 52 ; c ; ? BEL
370
+ * - Response: ESC ] 52 ; c ; <base64> BEL (or ST terminator)
371
+ *
372
+ * Supported by: Ghostty, Kitty, WezTerm, iTerm2, xterm, foot, tmux
373
+ */
374
+ /**
375
+ * Multi-format clipboard content.
376
+ *
377
+ * Plain text is always present. Optional rich formats allow applications
378
+ * to provide structured data for within-app paste without losing it
379
+ * through the plain-text-only system clipboard.
380
+ */
381
+ interface ClipboardData {
382
+ /** Plain text content (always present) */
383
+ text: string;
384
+ /** Markdown representation */
385
+ markdown?: string;
386
+ /** HTML representation */
387
+ html?: string;
388
+ /** App-specific structured data (e.g., node tree for structured paste) */
389
+ internal?: unknown;
390
+ }
391
+ /**
392
+ * Clipboard backend capabilities.
393
+ *
394
+ * `text` is always true — every backend supports plain text.
395
+ * Rich format support is backend-dependent.
396
+ */
397
+ interface ClipboardCapabilities {
398
+ readonly text: true;
399
+ readonly html?: boolean;
400
+ readonly markdown?: boolean;
401
+ readonly internal?: boolean;
402
+ }
403
+ /**
404
+ * Pluggable clipboard backend.
405
+ *
406
+ * Backends handle the transport of clipboard data to/from the system
407
+ * or an in-memory store. The framework writes ClipboardData; the backend
408
+ * decides what formats it can actually carry.
409
+ */
410
+ interface ClipboardBackend {
411
+ /** Write clipboard data. Backends may ignore formats they don't support. */
412
+ write(data: ClipboardData): void | Promise<void>;
413
+ /** Read clipboard contents as plain text. Not all backends support read. */
414
+ read?(): Promise<string>;
415
+ /** What formats this backend supports */
416
+ readonly capabilities: ClipboardCapabilities;
417
+ }
418
+ /** Minimal writable interface for clipboard output */
419
+ interface Writable {
420
+ write(data: string): boolean | void;
421
+ }
422
+ /**
423
+ * Upper bound on the decoded size of an OSC 52 clipboard payload.
424
+ *
425
+ * OSC 52 responses are attacker-influenceable: a hostile program on the far end
426
+ * of an SSH session, or a malicious terminal emulator, can emit an arbitrary
427
+ * base64 blob that arrives on stdin and is decoded here (see the
428
+ * `input-owner.ts` clipboard-response path that fires it as a paste). Node's
429
+ * base64 decoder never throws and imposes no size limit, so without a cap a
430
+ * single response could force an arbitrarily large allocation and then be fed
431
+ * into a focused guest as pasted input. Real clipboards are small — terminals
432
+ * themselves cap OSC 52 payloads around ~100 KB (see the `createOsc52Backend`
433
+ * quirks note) — so 1 MiB sits comfortably above any legitimate clipboard while
434
+ * keeping the decode bounded.
435
+ */
436
+ /**
437
+ * Create an OSC 52 clipboard backend.
438
+ *
439
+ * Writes plain text to the system clipboard via the terminal's OSC 52 support.
440
+ * Works across SSH sessions. Rich formats (markdown, html, internal) are
441
+ * silently ignored — OSC 52 only carries plain text.
442
+ *
443
+ * Quirks:
444
+ * - Some terminals limit payload size (~100KB)
445
+ * - tmux requires `set -g set-clipboard on`
446
+ * - Some terminals only support BEL terminator (not ST)
447
+ */
448
+ declare function createOsc52Backend(stdout: Writable): ClipboardBackend;
449
+ /**
450
+ * In-memory clipboard store for within-app paste.
451
+ *
452
+ * Stores the full ClipboardData including rich formats that OSC 52 can't carry.
453
+ * Used alongside OSC 52 so plain text goes to the system clipboard while
454
+ * rich data is available for internal paste operations.
455
+ */
456
+ declare function createInternalClipboardBackend(): ClipboardBackend & {
457
+ /** Get the stored clipboard data, or null if empty */getData(): ClipboardData | null; /** Get the timestamp of the last write */
458
+ getTimestamp(): number;
459
+ };
460
+ /**
461
+ * Create a composite clipboard that writes to multiple backends.
462
+ *
463
+ * Writes fan out to all backends. Reads come from the first backend
464
+ * that supports read (in order). This lets you do OSC 52 + internal
465
+ * store simultaneously: plain text goes to system clipboard, rich
466
+ * data stays in memory for structured paste.
467
+ */
468
+ declare function createCompositeClipboard(...backends: ClipboardBackend[]): ClipboardBackend;
469
+ /**
470
+ * Parse an OSC 52 clipboard response and decode the base64 content.
471
+ *
472
+ * Return semantics (see {@link ProtocolError} for the full contract):
473
+ * - `null` — input is NOT an OSC 52 clipboard response (no prefix, or a
474
+ * query marker `?` rather than a response). Callers in a discriminator
475
+ * chain treat this as "next parser please."
476
+ * - `throw ProtocolError` — input HAS the OSC 52 prefix (we committed to
477
+ * this protocol) but is malformed (e.g., missing terminator). Loud
478
+ * failure is required by bead 15127 acceptance line 22.
479
+ *
480
+ * Handles both BEL (\x07) and ST (ESC \) terminators.
481
+ */
482
+ declare function parseClipboardResponse(input: string): string | null;
483
+ //#endregion
484
+ //#region packages/headless/src/pointer.d.ts
485
+ interface Position {
486
+ x: number;
487
+ y: number;
488
+ }
489
+ //#endregion
490
+ //#region packages/ag-term/src/drag-events.d.ts
491
+ /**
492
+ * Active drag session state.
493
+ * Created when pointer state machine emits startDrag, updated on updateDrag,
494
+ * cleared on finishDrag/cancelDrag.
495
+ */
496
+ interface DragState {
497
+ /** Whether a drag is currently active */
498
+ active: boolean;
499
+ /** The node being dragged (has draggable=true) */
500
+ source: AgNode;
501
+ /** Terminal position where the drag started */
502
+ startPos: Position;
503
+ /** Current drag position (updated on every pointer move) */
504
+ currentPos: Position;
505
+ /** Node currently under the cursor that accepts drops (has onDrop handler), or null */
506
+ dropTarget: AgNode | null;
507
+ }
508
+ //#endregion
509
+ //#region packages/headless/src/copy-mode.d.ts
510
+ /**
511
+ * Copy-mode state machine — pure TEA `(action, state) → [state, effects[]]`.
512
+ *
513
+ * Keyboard-driven selection mode (vim-like visual mode).
514
+ * When active, h/j/k/l navigate a cursor, v/V toggle visual selection,
515
+ * y yanks (copies) the selection and exits.
516
+ */
517
+ interface CopyModePosition {
518
+ col: number;
519
+ row: number;
520
+ }
521
+ interface CopyModeState {
522
+ /** Whether copy-mode is active */
523
+ active: boolean;
524
+ /** Current cursor position */
525
+ cursor: CopyModePosition;
526
+ /** Character-wise visual mode (v) */
527
+ visual: boolean;
528
+ /** Line-wise visual mode (V) */
529
+ visualLine: boolean;
530
+ /** Start of visual selection (set when visual mode is entered) */
531
+ anchor: CopyModePosition | null;
532
+ /** Buffer dimensions for boundary clamping */
533
+ bufferWidth: number;
534
+ bufferHeight: number;
535
+ }
536
+ //#endregion
537
+ //#region packages/ag-term/src/output.d.ts
538
+ /**
539
+ * Generate ANSI sequence to move cursor to position.
540
+ * Terminal positions are 1-indexed.
541
+ */
542
+ declare function moveCursor$1(x: number, y: number): string;
543
+ /**
544
+ * Generate ANSI sequence to move cursor up N lines.
545
+ */
546
+ declare function cursorUp(n: number): string;
547
+ /**
548
+ * Generate ANSI sequence to move cursor down N lines.
549
+ */
550
+ declare function cursorDown(n: number): string;
551
+ /**
552
+ * Generate ANSI sequence to move cursor right N columns.
553
+ */
554
+ declare function cursorRight(n: number): string;
555
+ /**
556
+ * Generate ANSI sequence to move cursor left N columns.
557
+ */
558
+ declare function cursorLeft(n: number): string;
559
+ /**
560
+ * Generate ANSI sequence to move cursor to column.
561
+ */
562
+ declare function cursorToColumn(x: number): string;
563
+ /**
564
+ * Terminal cursor shape. Combined with blink parameter in setCursorStyle().
565
+ */
566
+ type CursorShape = "block" | "underline" | "bar";
567
+ /**
568
+ * Set the terminal cursor shape via DECSCUSR (CSI Ps SP q).
569
+ *
570
+ * Supported by: xterm, Ghostty, Kitty, WezTerm, iTerm2, Alacritty, foot.
571
+ * Terminals that don't support it safely ignore the sequence.
572
+ *
573
+ * @param shape - "block", "underline", or "bar"
574
+ * @param blink - Whether the cursor should blink (default: false)
575
+ */
576
+ declare function setCursorStyle(shape: CursorShape, blink?: boolean): string;
577
+ /**
578
+ * Reset the terminal cursor style to the terminal's default (DECSCUSR 0).
579
+ */
580
+ declare function resetCursorStyle(): string;
581
+ declare const enableMouse: typeof enableMouse$1;
582
+ declare const disableMouse: typeof disableMouse$1;
583
+ /**
584
+ * Kitty keyboard protocol flags (bitfield).
585
+ *
586
+ * | Flag | Bit | Description |
587
+ * | ---- | --- | ---------------------------------------------- |
588
+ * | 1 | 0 | Disambiguate escape codes |
589
+ * | 2 | 1 | Report event types (press/repeat/release) |
590
+ * | 4 | 2 | Report alternate keys |
591
+ * | 8 | 3 | Report all keys as escape codes |
592
+ * | 16 | 4 | Report associated text |
593
+ */
594
+ declare const KittyFlags: {
595
+ readonly DISAMBIGUATE: 1;
596
+ readonly REPORT_EVENTS: 2;
597
+ readonly REPORT_ALTERNATE: 4;
598
+ readonly REPORT_ALL_KEYS: 8;
599
+ readonly REPORT_TEXT: 16;
600
+ };
601
+ /**
602
+ * Enable Kitty keyboard protocol (push mode).
603
+ * Sends CSI > flags u to opt into the specified modes.
604
+ * Default flags=11 (DISAMBIGUATE | REPORT_EVENTS | REPORT_ALL_KEYS) —
605
+ * enables modifier-only key reporting needed for useModifierKeys() Cmd tracking.
606
+ * Supported: Ghostty, Kitty, WezTerm, foot. Ignored by unsupported terminals.
607
+ *
608
+ * @param flags Bitfield of KittyFlags (default: DISAMBIGUATE)
609
+ */
610
+ declare const enableKittyKeyboard: typeof enableKittyKeyboard$1;
611
+ declare function queryKittyKeyboard(): string;
612
+ declare const disableKittyKeyboard: typeof disableKittyKeyboard$1;
613
+ /** BEL character — audible bell and legacy OSC string terminator. */
614
+ declare const BEL = "\u0007";
615
+ /**
616
+ * Set the terminal window title using OSC 2 (window title only).
617
+ * Does not affect icon title (tab name in some terminals).
618
+ * Widely supported: xterm, Ghostty, iTerm2, Kitty, WezTerm, Alacritty, foot.
619
+ */
620
+ declare function setWindowTitle(stdout: NodeJS.WriteStream, title: string): void;
621
+ /**
622
+ * Set both the window title and icon title using OSC 0.
623
+ * Some terminals treat OSC 0 as equivalent to OSC 2; others also change the
624
+ * dock/taskbar icon name.
625
+ */
626
+ declare function setWindowAndIconTitle(stdout: NodeJS.WriteStream, title: string): void;
627
+ /**
628
+ * Reset the terminal window title by sending an empty OSC 2 sequence.
629
+ * The terminal typically reverts to its default title (shell command, etc.).
630
+ */
631
+ declare function resetWindowTitle(stdout: NodeJS.WriteStream): void;
632
+ /** Report current working directory to the terminal via OSC 7.
633
+ * Used by terminals (iTerm2, Ghostty, WezTerm) for tab/split directory inheritance.
634
+ */
635
+ declare function reportDirectory(stdout: NodeJS.WriteStream, path: string): void;
636
+ /**
637
+ * Mouse cursor shape names for OSC 22.
638
+ *
639
+ * Uses X11/CSS cursor names. Supported by: Ghostty, Kitty (>=0.33), foot,
640
+ * WezTerm (partial). Terminals that don't support OSC 22 safely ignore it.
641
+ */
642
+ type MouseCursorShape = "default" | "text" | "pointer" | "crosshair" | "move" | "not-allowed" | "wait" | "help" | "grab" | "grabbing" | "col-resize" | "row-resize" | "ew-resize" | "ns-resize";
643
+ /**
644
+ * Generate OSC 22 sequence to set the mouse cursor shape.
645
+ *
646
+ * @param shape - X11/CSS cursor name
647
+ * @returns ANSI escape sequence string
648
+ */
649
+ declare function setMouseCursorShape(shape: MouseCursorShape): string;
650
+ /**
651
+ * Generate OSC 22 sequence to reset mouse cursor to default.
652
+ *
653
+ * @returns ANSI escape sequence string
654
+ */
655
+ declare function resetMouseCursorShape(): string;
656
+ declare const ANSI: {
657
+ readonly ESC: "\u001B";
658
+ readonly CSI: "\u001B[";
659
+ readonly CURSOR_HIDE: "\u001B[?25l";
660
+ readonly CURSOR_SHOW: "\u001B[?25h";
661
+ readonly CURSOR_HOME: "\u001B[H";
662
+ readonly SYNC_BEGIN: "\u001B[?2026h";
663
+ readonly SYNC_END: "\u001B[?2026l";
664
+ readonly RESET: "\u001B[0m";
665
+ readonly SGR: {
666
+ readonly bold: 1;
667
+ readonly dim: 2;
668
+ readonly italic: 3;
669
+ readonly underline: 4;
670
+ readonly blink: 5;
671
+ readonly inverse: 7;
672
+ readonly hidden: 8;
673
+ readonly strikethrough: 9;
674
+ readonly boldOff: 22;
675
+ readonly italicOff: 23;
676
+ readonly underlineOff: 24;
677
+ readonly blinkOff: 25;
678
+ readonly inverseOff: 27;
679
+ readonly hiddenOff: 28;
680
+ readonly strikethroughOff: 29;
681
+ readonly fgDefault: 39;
682
+ readonly fgBlack: 30;
683
+ readonly fgRed: 31;
684
+ readonly fgGreen: 32;
685
+ readonly fgYellow: 33;
686
+ readonly fgBlue: 34;
687
+ readonly fgMagenta: 35;
688
+ readonly fgCyan: 36;
689
+ readonly fgWhite: 37;
690
+ readonly fgBrightBlack: 90;
691
+ readonly fgBrightRed: 91;
692
+ readonly fgBrightGreen: 92;
693
+ readonly fgBrightYellow: 93;
694
+ readonly fgBrightBlue: 94;
695
+ readonly fgBrightMagenta: 95;
696
+ readonly fgBrightCyan: 96;
697
+ readonly fgBrightWhite: 97;
698
+ readonly bgDefault: 49;
699
+ readonly bgBlack: 40;
700
+ readonly bgRed: 41;
701
+ readonly bgGreen: 42;
702
+ readonly bgYellow: 43;
703
+ readonly bgBlue: 44;
704
+ readonly bgMagenta: 45;
705
+ readonly bgCyan: 46;
706
+ readonly bgWhite: 47;
707
+ readonly bgBrightBlack: 100;
708
+ readonly bgBrightRed: 101;
709
+ readonly bgBrightGreen: 102;
710
+ readonly bgBrightYellow: 103;
711
+ readonly bgBrightBlue: 104;
712
+ readonly bgBrightMagenta: 105;
713
+ readonly bgBrightCyan: 106;
714
+ readonly bgBrightWhite: 107;
715
+ };
716
+ readonly moveCursor: typeof moveCursor$1;
717
+ readonly cursorUp: typeof cursorUp;
718
+ readonly cursorDown: typeof cursorDown;
719
+ readonly cursorLeft: typeof cursorLeft;
720
+ readonly cursorRight: typeof cursorRight;
721
+ readonly cursorToColumn: typeof cursorToColumn;
722
+ };
723
+ //#endregion
724
+ //#region packages/ag-react/src/hooks/useCursor.d.ts
725
+ interface CursorPosition {
726
+ /** Column offset within the component (0-indexed) */
727
+ col: number;
728
+ /** Row offset within the component (0-indexed) */
729
+ row: number;
730
+ /** Whether the cursor should be visible. Default: true */
731
+ visible?: boolean;
732
+ /** Terminal cursor shape (DECSCUSR). Default: terminal default */
733
+ shape?: CursorShape;
734
+ }
735
+ interface CursorState {
736
+ /** Absolute terminal X position (0-indexed) */
737
+ x: number;
738
+ /** Absolute terminal Y position (0-indexed) */
739
+ y: number;
740
+ /** Whether cursor is visible */
741
+ visible: boolean;
742
+ /** Terminal cursor shape (DECSCUSR) */
743
+ shape?: CursorShape;
744
+ /**
745
+ * Identity of the `useCursor` instance that last wrote this state. Set
746
+ * automatically by the hook on each store write. Used by the
747
+ * clear-on-unmount + clear-on-hide branches to skip the clear when
748
+ * THIS instance no longer owns the state — preventing the last-writer-
749
+ * wins stomp where an inactive sibling instance clears the active
750
+ * one's cursor. See bead `@km/silvery/13011-usecursor-race`. Optional
751
+ * because legacy external writes (Ink compat, direct store pokes) may
752
+ * omit it.
753
+ */
754
+ owner?: number;
755
+ }
756
+ /**
757
+ * Imperative cursor accessors for non-React code (scheduler, output phase).
758
+ * Created by createCursorStore() and threaded to consumers that can't use hooks.
759
+ */
760
+ interface CursorAccessors {
761
+ getCursorState(): CursorState | null;
762
+ subscribeCursor(listener: () => void): () => void;
763
+ }
764
+ interface CursorStore {
765
+ state: CursorState | null;
766
+ listeners: Set<() => void>;
767
+ accessors: CursorAccessors;
768
+ setCursorState(state: CursorState | null): void;
769
+ }
770
+ /**
771
+ * Create an isolated cursor store. Each silvery instance gets one.
772
+ * Returns the store (for CursorProvider) and accessors (for scheduler/output).
773
+ */
774
+ declare function createCursorStore(): CursorStore;
775
+ /**
776
+ * Provider that gives its subtree an isolated cursor store.
777
+ * Wrap your silvery app root in this to isolate cursor state per instance.
778
+ */
779
+ declare function CursorProvider({
780
+ store,
781
+ children
782
+ }: {
783
+ store: CursorStore;
784
+ children?: ReactNode;
785
+ }): React.FunctionComponentElement<React.ProviderProps<CursorStore | null>>;
786
+ /** For testing -- reset global fallback state between tests. */
787
+ declare function resetCursorState(): void;
788
+ /**
789
+ * Show and position the terminal's blinking cursor within this component.
790
+ *
791
+ * The cursor position is relative to the component's screen position.
792
+ * Only one cursor can be active per silvery instance -- last caller with visible=true wins.
793
+ *
794
+ * Uses CursorContext if a CursorProvider is present (per-instance isolation).
795
+ * Falls back to module-level globals otherwise (backward compat).
796
+ *
797
+ * @deprecated Phase 2 of `km-silvery.view-as-layout-output` migrated cursor
798
+ * positioning from a React-effect-chain (`useCursor` → `useScrollRect` →
799
+ * `setCursorState`) to a layout-output prop (`<Box cursorOffset={…}>`). The
800
+ * prop path resolves absolute coordinates synchronously during the layout
801
+ * phase, so the very first frame after a conditional mount emits correct
802
+ * cursor ANSI — fixing `km-silvercode.cursor-startup-position` end-to-end.
803
+ *
804
+ * Migrate consumers by deleting the `useCursor({col, row, visible})` call
805
+ * and adding `cursorOffset={{col, row, visible}}` to the surrounding Box. The
806
+ * layout phase applies border + padding offsets automatically, so consumers
807
+ * no longer need to add `borderColOffset` / `borderRowOffset` manually.
808
+ *
809
+ * This hook remains as a back-compat wrapper that writes to the cursor
810
+ * store; the scheduler still reads the store as a fallback when no
811
+ * `cursorOffset` prop is set on any node. Slated for deletion once all
812
+ * in-tree consumers migrate (TextArea + TextInput already migrated; Ink
813
+ * compat goes through the store directly and is unaffected). See bead
814
+ * `km-silvery.delete-cursor-globals`.
815
+ */
816
+ declare function useCursor(position: CursorPosition): void;
817
+ //#endregion
818
+ //#region packages/ag-term/src/pipeline/output-phase.d.ts
819
+ interface OutputPhaseDiagnostics {
820
+ reason: "first-render" | "inline-first-render" | "inline-resize-incremental" | "inline-incremental" | "forced-full-render" | "dimension-mismatch" | "zero-diff" | "diff" | "native-scroll-diff";
821
+ mode: "fullscreen" | "inline";
822
+ width: number;
823
+ height: number;
824
+ prevWidth: number;
825
+ prevHeight: number;
826
+ changedCells?: number;
827
+ rawChangedCells?: number;
828
+ dirtyRows?: number;
829
+ }
830
+ /**
831
+ * Output-phase capabilities type.
832
+ *
833
+ * Post km-silvery.text-box-attr-props (2026-04-23):
834
+ * `underlineStyles` is now the per-style set (not just a boolean), so the
835
+ * output phase can downgrade individual styles — e.g. `"curly"` requested on
836
+ * a terminal that only supports `"single"` emits plain `SGR 4` instead of
837
+ * the unsupported `4:3`.
838
+ *
839
+ * Accepts either form at construction for backwards compatibility:
840
+ * - `boolean` — back-compat shorthand. `true` = all styles supported
841
+ * (modern terminals); `false` = only plain `SGR 4` works.
842
+ * - `readonly UnderlineStyle[]` — per-style granular set, matches
843
+ * `TerminalCaps.underlineStyles` directly.
844
+ *
845
+ * Internally the output phase always sees the array form (resolved by the
846
+ * ctx factory). Consumers check per-style via the `supportsUnderlineStyle`
847
+ * helper, or check "any extended support" via `caps.underlineStyles.length > 0`.
848
+ */
849
+ type OutputUnderlineStylesCap = boolean | readonly UnderlineStyle[];
850
+ interface OutputCaps {
851
+ /**
852
+ * Per-style underline support. Array form so the output phase can
853
+ * downgrade individual unsupported styles to plain SGR 4 (single).
854
+ * Empty array = plain SGR 4 only.
855
+ */
856
+ readonly underlineStyles: readonly UnderlineStyle[];
857
+ readonly underlineColor: boolean;
858
+ /**
859
+ * SGR 53 (overline) support. When false, the output phase skips
860
+ * emitting SGR 53/55 — the cell attr is still packed/diffed, but no
861
+ * escape sequence reaches the terminal. Defaults to true for modern
862
+ * terminals (Ghostty, iTerm2, xterm with extended attrs enabled).
863
+ */
864
+ readonly overline: boolean;
865
+ readonly colorLevel: TerminalCaps["colorLevel"];
866
+ }
867
+ /** Output phase function signature. */
868
+ interface OutputPhaseFn {
869
+ (prev: TerminalBuffer | null, next: TerminalBuffer, mode?: "fullscreen" | "inline", scrollbackOffset?: number, termRows?: number, cursorPos?: CursorState | null): string;
870
+ /** Reset inline cursor state. Used by useScrollback to clear cursor tracking on resize. */
871
+ resetInlineState?: () => void;
872
+ /** Get the current inline cursor row (relative to render region start). -1 if unknown. */
873
+ getInlineCursorRow?: () => number;
874
+ /** Promote frozen content to scrollback. Called by useScrollback to queue
875
+ * frozen content for the next render — the output phase writes frozen + live
876
+ * content in a single target.write() to avoid flicker. */
877
+ promoteScrollback?: (frozenContent: string, frozenLineCount: number) => void;
878
+ }
879
+ interface OutputMeasurer {
880
+ graphemeWidth(grapheme: string): number;
881
+ readonly textSizing: boolean;
882
+ }
883
+ /**
884
+ * Create a scoped output phase that uses specific terminal capabilities.
885
+ *
886
+ * @param caps - Terminal capabilities for SGR code generation. Accepts
887
+ * `underlineStyles` as either a boolean (back-compat) or the per-style
888
+ * array form; see {@link OutputUnderlineStylesCap}.
889
+ * @param measurer - Width measurer for graphemeWidth/textSizing (avoids dual-module-loading issues)
890
+ */
891
+ declare function createOutputPhase(caps: {
892
+ underlineStyles?: OutputUnderlineStylesCap;
893
+ underlineColor?: boolean;
894
+ overline?: boolean;
895
+ colorLevel?: TerminalCaps["colorLevel"];
896
+ }, measurer?: OutputMeasurer): OutputPhaseFn;
897
+ //#endregion
898
+ //#region packages/ag-term/src/pipeline/types.d.ts
899
+ /**
900
+ * Context threaded through the render pipeline.
901
+ *
902
+ * Carries per-render resources that were previously accessed via module-level
903
+ * globals (e.g., `_scopedMeasurer` + `runWithMeasurer()`). Threading context
904
+ * explicitly eliminates save/restore patterns and makes the pipeline pure.
905
+ *
906
+ * Phase 1: measurer only.
907
+ * Phase 2: NodeRenderState for per-node params.
908
+ * Phase 3: instrumentation/diagnostics fields (optional — fall back to
909
+ * module-level globals when absent for backward compat).
910
+ */
911
+ interface PipelineContext {
912
+ readonly measurer: Measurer;
913
+ readonly instrumentEnabled?: boolean;
914
+ readonly stats?: RenderPhaseStats;
915
+ readonly nodeTrace?: NodeTraceEntry[];
916
+ readonly nodeTraceEnabled?: boolean;
917
+ readonly bgConflictMode?: BgConflictMode;
918
+ readonly warnedBgConflicts?: Set<string>;
919
+ }
920
+ /**
921
+ * Background conflict detection mode.
922
+ * Set via SILVERY_BG_CONFLICT env var: 'ignore' | 'warn' | 'throw'
923
+ */
924
+ type BgConflictMode = "ignore" | "warn" | "throw";
925
+ /**
926
+ * Per-node trace entry for SILVERY_STRICT diagnosis.
927
+ */
928
+ interface NodeTraceEntry {
929
+ id: string;
930
+ type: string;
931
+ depth: number;
932
+ rect: string;
933
+ prevLayout: string;
934
+ hasPrev: boolean;
935
+ ancestorCleared: boolean;
936
+ flags: string;
937
+ decision: string;
938
+ layoutChanged: boolean;
939
+ contentAreaAffected?: boolean;
940
+ contentRegionCleared?: boolean;
941
+ childrenNeedFreshRender?: boolean;
942
+ childHasPrev?: boolean;
943
+ childAncestorCleared?: boolean;
944
+ skipBgFill?: boolean;
945
+ bgColor?: string;
946
+ }
947
+ /**
948
+ * Mutable stats counters for render phase instrumentation.
949
+ * Reset after each renderPhase call.
950
+ */
951
+ interface RenderPhaseStats {
952
+ nodesVisited: number;
953
+ nodesRendered: number;
954
+ nodesSkipped: number;
955
+ textNodes: number;
956
+ boxNodes: number;
957
+ clearOps: number;
958
+ /**
959
+ * Count of text nodes that took the per-segment style-only restyle fast path
960
+ * (skips collectTextWithBg→formatTextLines→renderGraphemes; restyles existing
961
+ * cells in place per child span). See render-text.ts `restyleTextSegments`.
962
+ */
963
+ textRestyleFastPath: number;
964
+ noPrevBuffer: number;
965
+ flagContentDirty: number;
966
+ flagStylePropsDirty: number;
967
+ flagLayoutChanged: number;
968
+ flagSubtreeDirty: number;
969
+ flagChildrenDirty: number;
970
+ flagChildPositionChanged: number;
971
+ flagAncestorLayoutChanged: number;
972
+ scrollContainerCount: number;
973
+ scrollViewportCleared: number;
974
+ scrollClearReason: string;
975
+ normalChildrenRepaint: number;
976
+ normalRepaintReason: string;
977
+ /**
978
+ * Count of children force-rendered because an earlier first-pass sibling's
979
+ * boxRect overlapped them. CSS paint order requires later siblings to win
980
+ * at any overlap; on incremental renders the earlier sibling's painting
981
+ * destroys the later sibling's pixels in the cloned buffer, so the later
982
+ * sibling must repaint even when its own dirty flags are clean.
983
+ */
984
+ siblingOverlapForced: number;
985
+ cascadeMinDepth: number;
986
+ cascadeNodes: string;
987
+ _noopSkip: number;
988
+ _prevBufferNull: number;
989
+ _prevBufferDimMismatch: number;
990
+ _hasPrevBuffer: number;
991
+ _layoutW: number;
992
+ _layoutH: number;
993
+ _prevW: number;
994
+ _prevH: number;
995
+ _callCount: number;
996
+ }
997
+ //#endregion
998
+ //#region packages/ag-term/src/render-adapter.d.ts
999
+ /**
1000
+ * Render Adapter Abstraction
1001
+ *
1002
+ * This module defines the interfaces that allow silvery to render to different
1003
+ * targets (terminal, canvas, etc.) while keeping the core layout and
1004
+ * reconciliation logic portable.
1005
+ */
1006
+ interface TextMeasureStyle {
1007
+ bold?: boolean;
1008
+ italic?: boolean;
1009
+ fontSize?: number;
1010
+ fontFamily?: string;
1011
+ }
1012
+ interface TextMeasureResult {
1013
+ width: number;
1014
+ height: number;
1015
+ }
1016
+ interface TextMeasurer {
1017
+ /**
1018
+ * Measure text dimensions.
1019
+ * Returns width in adapter units (cells for terminal, pixels for canvas).
1020
+ */
1021
+ measureText(text: string, style?: TextMeasureStyle): TextMeasureResult;
1022
+ /**
1023
+ * Get the line height for the given style.
1024
+ */
1025
+ getLineHeight(style?: TextMeasureStyle): number;
1026
+ }
1027
+ interface RenderStyle {
1028
+ /** Cross-target hyperlink carried by the rendered text cells. */
1029
+ hyperlink?: string;
1030
+ fg?: string;
1031
+ bg?: string;
1032
+ attrs?: {
1033
+ bold?: boolean;
1034
+ dim?: boolean;
1035
+ italic?: boolean;
1036
+ underline?: boolean;
1037
+ underlineStyle?: "single" | "double" | "curly" | "dotted" | "dashed";
1038
+ underlineColor?: string; /** Overline — SGR 53/55. Independent of underline. */
1039
+ overline?: boolean;
1040
+ strikethrough?: boolean;
1041
+ inverse?: boolean;
1042
+ };
1043
+ }
1044
+ interface RenderBuffer {
1045
+ readonly width: number;
1046
+ readonly height: number;
1047
+ /**
1048
+ * Fill a rectangle with a style.
1049
+ */
1050
+ fillRect(x: number, y: number, width: number, height: number, style: RenderStyle): void;
1051
+ /**
1052
+ * Draw text at a position.
1053
+ */
1054
+ drawText(x: number, y: number, text: string, style: RenderStyle): void;
1055
+ /**
1056
+ * Draw a single character at a position.
1057
+ */
1058
+ drawChar(x: number, y: number, char: string, style: RenderStyle): void;
1059
+ /**
1060
+ * Check if coordinates are within bounds.
1061
+ */
1062
+ inBounds(x: number, y: number): boolean;
1063
+ /**
1064
+ * Draw a filled rounded rectangle with optional border stroke.
1065
+ * Canvas-only — terminal adapters don't implement this.
1066
+ */
1067
+ fillRoundedRect?(x: number, y: number, width: number, height: number, radius: number, fill: string | undefined, stroke: string | undefined, lineWidth?: number): void;
1068
+ }
1069
+ interface BorderChars {
1070
+ topLeft: string;
1071
+ topRight: string;
1072
+ bottomLeft: string;
1073
+ bottomRight: string;
1074
+ horizontal: string;
1075
+ vertical: string;
1076
+ /** Bottom horizontal character. When absent, falls back to `horizontal`. */
1077
+ bottomHorizontal?: string;
1078
+ /** Right vertical character. When absent, falls back to `vertical`. */
1079
+ rightVertical?: string;
1080
+ }
1081
+ interface RenderAdapter {
1082
+ /** Adapter name for debugging */
1083
+ name: string;
1084
+ /** Text measurement for this adapter */
1085
+ measurer: TextMeasurer;
1086
+ /**
1087
+ * Create a buffer for rendering.
1088
+ */
1089
+ createBuffer(width: number, height: number): RenderBuffer;
1090
+ /**
1091
+ * Flush the buffer to the output (terminal, canvas, etc.).
1092
+ * For terminal: returns ANSI diff string.
1093
+ * For canvas: draws directly, returns void.
1094
+ */
1095
+ flush(buffer: RenderBuffer, prevBuffer: RenderBuffer | null): string | void;
1096
+ /**
1097
+ * Get border characters for the given style.
1098
+ */
1099
+ getBorderChars(style: string): BorderChars;
1100
+ }
1101
+ //#endregion
1102
+ //#region packages/ag/src/layout-signals.d.ts
1103
+ /**
1104
+ * Writable signal — call with no args to read, call with value to write.
1105
+ */
1106
+ type WritableSignal<T> = {
1107
+ (): T;
1108
+ (value: T): void;
1109
+ };
1110
+ /**
1111
+ * Reactive projection of `AgNode.scrollState` — the layout-phase's pixel-space
1112
+ * truth about what's visible in an `overflow="scroll"` container.
1113
+ *
1114
+ * This is the **single source of truth** that virtualization consumers (like
1115
+ * `useVirtualizer` + `ListView`) read to decide which items to render. By
1116
+ * subscribing to this signal instead of independently computing their own
1117
+ * visible range, consumers cannot diverge from what layout-phase actually
1118
+ * laid out on screen.
1119
+ *
1120
+ * Fields are pixel-space integers already rounded by the layout engine —
1121
+ * re-using them (instead of recomputing via `sumHeights`) guarantees
1122
+ * `leadingHeight == scrollOffset` by construction.
1123
+ *
1124
+ * `null` for non-scroll containers and for scroll containers before the first
1125
+ * layout pass (bootstrap state — virtualizers must fall back to estimates).
1126
+ */
1127
+ interface ScrollStateSnapshot {
1128
+ /** Current scroll offset in terminal rows (pixel-space, pre-rounded). */
1129
+ readonly offset: number;
1130
+ /** Total content height (all children) in rows. */
1131
+ readonly contentHeight: number;
1132
+ /** Visible height (container height minus borders/padding). */
1133
+ readonly viewportHeight: number;
1134
+ /** Index of the first visible child (flexbox-measured). */
1135
+ readonly firstVisibleChild: number;
1136
+ /** Index of the last visible child (flexbox-measured). */
1137
+ readonly lastVisibleChild: number;
1138
+ /** Count of items hidden above the viewport. */
1139
+ readonly hiddenAbove: number;
1140
+ /** Count of items hidden below the viewport. */
1141
+ readonly hiddenBelow: number;
1142
+ }
1143
+ /**
1144
+ * Caret rect — absolute terminal coordinates of the caret declared on a
1145
+ * Box via `cursorOffset`, computed during the layout phase as the peer of
1146
+ * `scrollRect` / `screenRect` / `boxRect` / `contentRect`.
1147
+ *
1148
+ * Width/height are always 1 (the caret occupies a single cell). The
1149
+ * `visible` flag is a separate property because layout still computes the
1150
+ * coordinates even when the caret is hidden — that lets toggling
1151
+ * `visible` re-emit the caret without re-running layout.
1152
+ *
1153
+ * `shape` is **deprecated** — the terminal layer now derives the shape
1154
+ * from focus + editable state via `resolveCaretStyle` in `@silvery/ag-term`.
1155
+ * The field is kept for one cycle so external readers that were already
1156
+ * forwarding `cursor.shape` to DECSCUSR keep working; new code MUST NOT
1157
+ * branch on this field. See bead `km-silvery.cursor-invariants` invariant 6.
1158
+ */
1159
+ interface CursorRect {
1160
+ /** Absolute terminal X column (0-indexed) */
1161
+ readonly x: number;
1162
+ /** Absolute terminal Y row (0-indexed) */
1163
+ readonly y: number;
1164
+ /** Whether the caret should be visible on this frame. */
1165
+ readonly visible: boolean;
1166
+ /**
1167
+ * @deprecated Target-specific. Read focus state from the active cursor
1168
+ * node via `resolveCaretStyle` in `@silvery/ag-term` instead. Removed in
1169
+ * the next cycle.
1170
+ */
1171
+ readonly shape?: CursorShape$1;
1172
+ }
1173
+ /**
1174
+ * All reactive signals for an AgNode.
1175
+ *
1176
+ * Combined rect signals (layout outputs) + node signals (content/state).
1177
+ * One interface, one WeakMap, one sync function.
1178
+ */
1179
+ interface LayoutSignals {
1180
+ readonly boxRect: WritableSignal<Rect | null>;
1181
+ readonly scrollRect: WritableSignal<Rect | null>;
1182
+ readonly screenRect: WritableSignal<Rect | null>;
1183
+ readonly boxRectCommitted: WritableSignal<Rect | null>;
1184
+ readonly scrollRectCommitted: WritableSignal<Rect | null>;
1185
+ readonly screenRectCommitted: WritableSignal<Rect | null>;
1186
+ /**
1187
+ * Content-box rect — `boxRect` minus border and padding (CSS content area).
1188
+ * Peer of `boxRect`/`scrollRect`/`screenRect`, synced after layout. Null
1189
+ * when the node has no boxRect yet (pre-layout) or is not a Box.
1190
+ *
1191
+ * This is the canonical origin for caret positioning, popover anchors,
1192
+ * selection fragments, and any feature that needs to draw "inside" a Box's
1193
+ * content area without re-deriving the border/padding math at the call
1194
+ * site. `computeCursorRect` reads from this rect — Phase 4 / overlay-anchor
1195
+ * work will too. See `km-silvery.cursor-invariants` invariant 3.
1196
+ */
1197
+ readonly contentRect: WritableSignal<Rect | null>;
1198
+ /**
1199
+ * Absolute terminal coordinates of the caret declared by this node's
1200
+ * `BoxProps.cursorOffset`. Null when the node has no cursorOffset prop, or
1201
+ * before the first layout pass populates `scrollRect`.
1202
+ *
1203
+ * Phase 2 of `km-silvery.view-as-layout-output` — the scheduler reads this
1204
+ * signal (rather than `cursorStore.getCursorState()`) to emit caret
1205
+ * positioning ANSI. Because layout phase runs synchronously before each
1206
+ * render, the very first frame after mount sees the correct caret — no
1207
+ * effect-chain stale-read on conditional mounts.
1208
+ */
1209
+ readonly cursorRect: WritableSignal<CursorRect | null>;
1210
+ /**
1211
+ * Focused-node id declared by this node's `BoxProps.focused`. The value is
1212
+ * the node's `id` (preferred) or `testID` when `props.focused === true`,
1213
+ * else `null`. Phase 4a of `km-silvery.view-as-layout-output` — the
1214
+ * focus-renderer reads this signal (and/or `findActiveFocusedNodeId(root)`)
1215
+ * to paint focus styling without going through the `useFocus` →
1216
+ * `FocusManager` → `useSyncExternalStore` effect chain.
1217
+ *
1218
+ * Per-node by design (peer of `cursorRect`): each Box that participates in
1219
+ * focus carries its own declared id here, and the tree-walk lookup picks
1220
+ * the deepest visible declarer. Unmount is handled by WeakMap GC + the
1221
+ * per-frame recompute in `syncRectSignals` clearing back to null when the
1222
+ * prop is removed. See bead `km-silvery.phase4-split-focus-selection`.
1223
+ */
1224
+ readonly focusedNodeId: WritableSignal<string | null>;
1225
+ /**
1226
+ * Geometric output of `BoxProps.selectionIntent` — the list of rectangles
1227
+ * (one per visual line spanned) that the selection renderer should paint
1228
+ * with highlight bg this frame. Empty array when the node declares no
1229
+ * `selectionIntent` or when the intent is collapsed (`from === to`).
1230
+ *
1231
+ * Phase 4b of `km-silvery.view-as-layout-output` — peer of `cursorRect`
1232
+ * (caret) and `focusedNodeId` (focus). The selection renderer reads this
1233
+ * signal (and/or `findActiveSelectionFragments(root)`) to paint highlight
1234
+ * styling without going through the legacy `SelectionFeature` capability
1235
+ * + `useSelection` `useSyncExternalStore` chain.
1236
+ *
1237
+ * Per-node by design: each Box that participates in selection carries its
1238
+ * own fragments here. The aggregator (`findActiveSelectionFragments`)
1239
+ * concatenates fragments across all mounted declarers — multi-node
1240
+ * selection composes for free. Stale-cleanup is handled by WeakMap GC +
1241
+ * the per-frame recompute in `syncRectSignals` clearing back to the empty
1242
+ * sentinel when the prop is removed (mirrors cursor invariant 5 + focus
1243
+ * invariant 3). See bead `km-silvery.phase4-split-focus-selection`.
1244
+ */
1245
+ readonly selectionFragments: WritableSignal<readonly Rect[]>;
1246
+ readonly scrollState: WritableSignal<ScrollStateSnapshot | null>;
1247
+ /**
1248
+ * Geometric output of `BoxProps.anchorRef` — the rect that other Boxes'
1249
+ * decorations resolve to when they reference this anchor by id. The
1250
+ * registered rect is the Box's `contentRect` (border + padding excluded);
1251
+ * edge-specific rects are derived by `placeFloating` at consumption time.
1252
+ *
1253
+ * Phase 4c of `km-silvery.view-as-layout-output` (overlay-anchor v1) — peer
1254
+ * of `cursorRect`/`focusedNodeId`/`selectionFragments`. The tree-walk
1255
+ * lookup `findAnchor(root, id)` reads this signal (and falls back to
1256
+ * `computeAnchorRect` for nodes without signals).
1257
+ *
1258
+ * Null when:
1259
+ * - the node has no `anchorRef` BoxProp, OR
1260
+ * - `contentRect` is unavailable (pre-layout / clipped to zero size).
1261
+ */
1262
+ readonly anchorRect: WritableSignal<Rect | null>;
1263
+ /**
1264
+ * Absolute terminal coordinates of the HARDWARE-PARK cell declared by this
1265
+ * node's `BoxProps.parkOffset` — where a managed frame parks (then hides) the
1266
+ * hardware cursor when this node owns the frame. Position-only (1×1 rect);
1267
+ * null when the node has no `parkOffset` prop or before the first layout pass.
1268
+ *
1269
+ * Peer of `cursorRect`, but NON-focus-gated: the tree-walk lookup
1270
+ * `findActiveParkRect(root)` picks the deepest declarer regardless of focus or
1271
+ * visibility, so a managed frame always has a benign park cell and never falls
1272
+ * back to the box origin / `home(0,0)` (@km/code/v0.2/19702).
1273
+ */
1274
+ readonly parkRect: WritableSignal<Rect | null>;
1275
+ /**
1276
+ * Geometric output of `BoxProps.decorations` — the resolved per-decoration
1277
+ * rect list this frame. Each entry carries the source kind, id, and rects
1278
+ * (popover/tooltip → one rect at the placed position; highlight → one rect
1279
+ * within the owning Box's content area).
1280
+ *
1281
+ * v1 emits one rect per decoration. The list mirrors the BoxProp's order so
1282
+ * paint order is deterministic. When an anchor lookup fails (popover/tooltip
1283
+ * with no matching `anchorRef`), the entry's `rects` is empty — the
1284
+ * renderer skips it.
1285
+ *
1286
+ * Phase 4c of `km-silvery.view-as-layout-output` (overlay-anchor v1).
1287
+ */
1288
+ readonly decorationRects: WritableSignal<readonly DecorationRect[]>;
1289
+ readonly textContent: WritableSignal<string | undefined>;
1290
+ readonly focused: WritableSignal<boolean>;
1291
+ }
1292
+ /**
1293
+ * Geometric output of one `Decoration` entry — the resolved rects for paint
1294
+ * time, plus the source kind/id so the renderer can dispatch by kind.
1295
+ *
1296
+ * Phase 4c of `km-silvery.view-as-layout-output` (overlay-anchor v1).
1297
+ *
1298
+ * v1 emits one rect per decoration. Soft-wrap aware highlight fragmentation
1299
+ * (multiple rects per highlight) is deferred to v2 — same path as
1300
+ * `selectionFragments` once the find/replace consumer ships.
1301
+ *
1302
+ * `rects` may be empty when an anchor lookup failed (popover/tooltip with a
1303
+ * missing `anchorId`); consumers SHOULD skip empty entries rather than
1304
+ * paint a 0×0 rect.
1305
+ */
1306
+ interface DecorationRect {
1307
+ /** Decoration kind from the source `Decoration` entry. */
1308
+ readonly kind: Decoration["kind"];
1309
+ /** Stable id from the source `Decoration` entry. */
1310
+ readonly id: string;
1311
+ /** Resolved rects in absolute terminal cell space. May be empty. */
1312
+ readonly rects: readonly Rect[];
1313
+ }
1314
+ //#endregion
1315
+ //#region packages/ag-term/src/pipeline/index.d.ts
1316
+ /**
1317
+ * Options for render pipeline callers.
1318
+ */
1319
+ interface ExecuteRenderOptions {
1320
+ /**
1321
+ * Render mode: fullscreen or inline.
1322
+ * Default: 'fullscreen'
1323
+ */
1324
+ mode?: "fullscreen" | "inline";
1325
+ /**
1326
+ * Skip notifying layout subscribers.
1327
+ * Use for static/one-shot renders where layout feedback isn't needed.
1328
+ * Default: false
1329
+ */
1330
+ skipLayoutNotifications?: boolean;
1331
+ /**
1332
+ * Skip scroll state updates.
1333
+ * Use for fresh render comparisons (SILVERY_STRICT) to avoid mutating state.
1334
+ * Default: false
1335
+ */
1336
+ skipScrollStateUpdates?: boolean;
1337
+ /**
1338
+ * Number of lines written to stdout between renders (inline mode only).
1339
+ * Used to adjust cursor positioning when external code (e.g., useScrollback)
1340
+ * writes directly to stdout between renders.
1341
+ * Default: 0
1342
+ */
1343
+ scrollbackOffset?: number;
1344
+ /**
1345
+ * Terminal height in rows (inline mode only).
1346
+ * Used to clamp cursor-up offset when content exceeds terminal height.
1347
+ * Without this, content taller than the terminal causes rendering corruption
1348
+ * because cursor-up can't reach lines that scrolled off screen.
1349
+ */
1350
+ termRows?: number;
1351
+ /**
1352
+ * Cursor position from useCursor() (inline mode only).
1353
+ * When provided, the output phase positions the real terminal cursor
1354
+ * at this location instead of leaving it at the end of content.
1355
+ */
1356
+ cursorPos?: CursorState | null;
1357
+ }
1358
+ /**
1359
+ * Pipeline configuration from withRender().
1360
+ * Carries term-scoped width measurer and output phase.
1361
+ */
1362
+ interface PipelineConfig {
1363
+ /** Width measurer scoped to terminal capabilities */
1364
+ readonly measurer: Measurer;
1365
+ /** Output phase function scoped to terminal capabilities */
1366
+ readonly outputPhaseFn: OutputPhaseFn;
1367
+ }
1368
+ //#endregion
1369
+ //#region packages/ag/src/cls.d.ts
1370
+ /**
1371
+ * Why a layout shift happened. Used to filter "expected" shifts (the user
1372
+ * scrolled, content arrived in a streaming view) from "unexpected" shifts
1373
+ * (a code fence resized mid-stream, a status line bounced) — only the
1374
+ * latter fail CLS strict checks.
1375
+ */
1376
+ type ReflowReason = "user-action" | "unexpected" | "animation" | "content-arrival";
1377
+ /**
1378
+ * Classifier function — given a block + rect transition, returns the
1379
+ * reflow reason. The capture API passes a classifier that inspects layout
1380
+ * context (user-action vs streamed content vs unsolicited reflow). Default
1381
+ * classifier returns "unexpected" — most pessimistic, captures the bug
1382
+ * class CLS is designed to detect.
1383
+ */
1384
+ type ReasonClassifier = (blockId: string, fromRect: Rect, toRect: Rect, frameTimestamp: number) => ReflowReason;
1385
+ interface LayoutShift {
1386
+ /** Stable identifier for the shifted block. */
1387
+ blockId: string;
1388
+ /** Position + size in the previous frame. */
1389
+ fromRect: Rect;
1390
+ /** Position + size in the current frame. */
1391
+ toRect: Rect;
1392
+ /** Wall-clock timestamp at frame end (ms since epoch). */
1393
+ frameTimestamp: number;
1394
+ /** Why the shift happened — see ReflowReason for taxonomy. */
1395
+ reflowReason: ReflowReason;
1396
+ }
1397
+ interface CLSReport {
1398
+ /** All shifts observed in the capture window. */
1399
+ shifts: readonly LayoutShift[];
1400
+ /** Sum of (area × distance) over all shifts (CLS metric proper). */
1401
+ cumulativeScore: number;
1402
+ /** Subset of shifts with reflowReason="unexpected" — the actionable ones. */
1403
+ unexpectedShifts: readonly LayoutShift[];
1404
+ }
1405
+ //#endregion
1406
+ //#region packages/ag-react/src/debug/render-path.d.ts
1407
+ /**
1408
+ * A summary of one node in a render-path or mount-tree dump.
1409
+ * The shape is JSON-serializable for snapshot tests.
1410
+ */
1411
+ interface RenderPathNode {
1412
+ /** Component name (data-component prop, or `${hostType}#${testID|id}`, or hostType) */
1413
+ name: string;
1414
+ /** AgNode host type (silvery-box, silvery-text, silvery-root) */
1415
+ type: AgNodeType;
1416
+ /** Optional content-relative position from layout phase */
1417
+ boxRect?: {
1418
+ x: number;
1419
+ y: number;
1420
+ width: number;
1421
+ height: number;
1422
+ };
1423
+ }
1424
+ /** Recursive mount tree — name + children for snapshot-friendly dumps. */
1425
+ interface MountTree extends RenderPathNode {
1426
+ children: MountTree[];
1427
+ }
1428
+ //#endregion
1429
+ //#region packages/test/src/auto-locator.d.ts
1430
+ /**
1431
+ * Filter options for locator narrowing
1432
+ */
1433
+ interface FilterOptions {
1434
+ /** Match nodes containing this text */
1435
+ hasText?: string | RegExp;
1436
+ /** Match nodes with this testID */
1437
+ hasTestId?: string;
1438
+ /** Match nodes with this attribute value */
1439
+ has?: {
1440
+ attr: string;
1441
+ value?: string;
1442
+ };
1443
+ }
1444
+ /**
1445
+ * AutoLocator interface - lazy, self-refreshing reference to nodes
1446
+ */
1447
+ interface AutoLocator {
1448
+ getByText(text: string | RegExp): AutoLocator;
1449
+ getByTestId(id: string): AutoLocator;
1450
+ locator(selector: string): AutoLocator;
1451
+ filter(options: FilterOptions): AutoLocator;
1452
+ filter(predicate: (node: AgNode) => boolean): AutoLocator;
1453
+ first(): AutoLocator;
1454
+ last(): AutoLocator;
1455
+ nth(index: number): AutoLocator;
1456
+ resolve(): AgNode | null;
1457
+ resolveAll(): AgNode[];
1458
+ count(): number;
1459
+ textContent(): string;
1460
+ getAttribute(name: string): string | undefined;
1461
+ boundingBox(): Rect | null;
1462
+ isVisible(): boolean;
1463
+ }
1464
+ /**
1465
+ * Create an AutoLocator from a container getter function.
1466
+ * The getter is called fresh on each resolution.
1467
+ */
1468
+ declare function createAutoLocator(getContainer: () => AgNode, opts?: {
1469
+ strict?: boolean;
1470
+ }): AutoLocator;
1471
+ //#endregion
1472
+ //#region packages/ag-term/src/app.d.ts
1473
+ /**
1474
+ * App interface - unified return type from render()
1475
+ */
1476
+ /**
1477
+ * Fluent chain of App actions. Each action method returns `ChainableApp`
1478
+ * — a `PromiseLike<App>` that exposes the same action methods so calls
1479
+ * can be composed without explicit `await` between every step.
1480
+ *
1481
+ * ```ts
1482
+ * await app.keyDown("Super").hover(x, y).keyUp("Super")
1483
+ * ```
1484
+ *
1485
+ * The returned chain `.then`-s into the App, so existing `await
1486
+ * app.action(...)` calls continue to receive the App instance — the
1487
+ * change is purely additive at the call site.
1488
+ *
1489
+ * Bead: @km/silvery/fluent-chain-actions.
1490
+ */
1491
+ interface ChainableApp extends PromiseLike<App> {
1492
+ press(key: string): ChainableApp;
1493
+ keyDown(key: string): ChainableApp;
1494
+ keyUp(key: string): ChainableApp;
1495
+ pressSequence(...keys: string[]): ChainableApp;
1496
+ type(text: string): ChainableApp;
1497
+ click(x: number, y: number, options?: {
1498
+ button?: number;
1499
+ shift?: boolean;
1500
+ meta?: boolean;
1501
+ ctrl?: boolean;
1502
+ cmd?: boolean;
1503
+ }): ChainableApp;
1504
+ doubleClick(x: number, y: number, options?: {
1505
+ button?: number;
1506
+ shift?: boolean;
1507
+ meta?: boolean;
1508
+ ctrl?: boolean;
1509
+ cmd?: boolean;
1510
+ }): ChainableApp;
1511
+ hover(x: number, y: number, options?: {
1512
+ shift?: boolean;
1513
+ meta?: boolean;
1514
+ ctrl?: boolean;
1515
+ cmd?: boolean;
1516
+ }): ChainableApp;
1517
+ wheel(x: number, y: number, delta: number, options?: {
1518
+ shift?: boolean;
1519
+ meta?: boolean;
1520
+ ctrl?: boolean;
1521
+ cmd?: boolean;
1522
+ }): ChainableApp;
1523
+ }
1524
+ interface App {
1525
+ /** Full rendered text (no ANSI codes) */
1526
+ readonly text: string;
1527
+ /** Full rendered text with ANSI styling */
1528
+ readonly ansi: string;
1529
+ /** Per-line plain text array (no ANSI codes) */
1530
+ readonly lines: string[];
1531
+ /** Frame width in terminal columns */
1532
+ readonly width: number;
1533
+ /** Frame height in terminal rows */
1534
+ readonly height: number;
1535
+ /** Get the cell at the given column and row (resolved styling) */
1536
+ cell(col: number, row: number): FrameCell;
1537
+ /** Check whether the plain text contains the given substring */
1538
+ containsText(text: string): boolean;
1539
+ /** Get node at content coordinates */
1540
+ nodeAt(x: number, y: number): AgNode | null;
1541
+ /** Get locator by testID attribute */
1542
+ getByTestId(id: string): AutoLocator;
1543
+ /** Get locator by text content */
1544
+ getByText(text: string | RegExp): AutoLocator;
1545
+ /** Get locator by CSS-style selector */
1546
+ locator(selector: string): AutoLocator;
1547
+ /**
1548
+ * Send a single key press. Emits the bare Kitty CSI u shape
1549
+ * (no `:eventType` byte) — the parser defaults to "press" without
1550
+ * one. Equivalent to a full down+up keystroke for tests asserting
1551
+ * "user typed key X". For held-state scenarios (Cmd-hover popovers,
1552
+ * multi-key chords) use `keyDown` / `keyUp` which emit explicit
1553
+ * `:1` (press) and `:3` (release) event-type bytes.
1554
+ *
1555
+ * Both bare-press and explicit-`:1` shapes parse to
1556
+ * `{ eventType: "press" | undefined }` respectively; consumers that
1557
+ * test `eventType !== "release"` see them identically. The shape
1558
+ * difference is intentional: bare = transient single event, typed =
1559
+ * paired down/up lifecycle. Bead:
1560
+ * @km/silvery/keydown-keyup-test-primitives.
1561
+ */
1562
+ press(key: string): ChainableApp;
1563
+ /**
1564
+ * Send a key DOWN event without auto-release. Useful for held-modifier
1565
+ * scenarios — e.g., `app.keyDown("Super")` then `app.hover(x, y)` then
1566
+ * `app.keyUp("Super")` to drive a Cmd-hover popover that opens after a
1567
+ * dwell timer reads the (still-held) modifier from the input store.
1568
+ *
1569
+ * Requires Kitty keyboard protocol (`kittyMode: true`) for modifier keys —
1570
+ * legacy ANSI cannot represent Super (Cmd) alone.
1571
+ *
1572
+ * For a single press+release event (the common case) use `press()`. Bead:
1573
+ * @km/silvery/keydown-keyup-test-primitives.
1574
+ */
1575
+ keyDown(key: string): ChainableApp;
1576
+ /**
1577
+ * Send a key UP event. Pairs with `keyDown(key)`. Drops the implicit
1578
+ * modifier state (mouseState.keyboardModifiers + the input-store
1579
+ * modifier tracker) so subsequent events run without the modifier
1580
+ * asserted. Bead: @km/silvery/keydown-keyup-test-primitives.
1581
+ */
1582
+ keyUp(key: string): ChainableApp;
1583
+ /** Send multiple key presses */
1584
+ pressSequence(...keys: string[]): ChainableApp;
1585
+ /** Type text input */
1586
+ type(text: string): ChainableApp;
1587
+ /** Simulate a mouse click at (x, y) terminal coordinates */
1588
+ click(x: number, y: number, options?: {
1589
+ button?: number;
1590
+ shift?: boolean;
1591
+ meta?: boolean;
1592
+ ctrl?: boolean;
1593
+ cmd?: boolean;
1594
+ }): ChainableApp;
1595
+ /** Simulate a double-click at (x, y) terminal coordinates */
1596
+ doubleClick(x: number, y: number, options?: {
1597
+ button?: number;
1598
+ shift?: boolean;
1599
+ meta?: boolean;
1600
+ ctrl?: boolean;
1601
+ cmd?: boolean;
1602
+ }): ChainableApp;
1603
+ /** Simulate a mouse move/hover at (x, y) terminal coordinates */
1604
+ hover(x: number, y: number, options?: {
1605
+ shift?: boolean;
1606
+ meta?: boolean;
1607
+ ctrl?: boolean;
1608
+ cmd?: boolean;
1609
+ }): ChainableApp;
1610
+ /** Simulate a mouse wheel event at (x, y) with delta (-1=up, +1=down) */
1611
+ wheel(x: number, y: number, delta: number, options?: {
1612
+ shift?: boolean;
1613
+ meta?: boolean;
1614
+ ctrl?: boolean;
1615
+ cmd?: boolean;
1616
+ }): ChainableApp;
1617
+ /** Resize the virtual terminal and re-render. Only available in test renderer. */
1618
+ resize(cols: number, rows: number): void;
1619
+ /** Wait until app exits */
1620
+ run(): Promise<void>;
1621
+ /** Bound terminal for screen-space access */
1622
+ readonly term: BoundTerm;
1623
+ /** Re-render with a new element */
1624
+ rerender(element: ReactNode): void;
1625
+ /** Unmount the component and clean up */
1626
+ unmount(): void;
1627
+ /** Dispose (alias for unmount) — enables `using` */
1628
+ [Symbol.dispose](): void;
1629
+ /** Promise that resolves when the app exits (alias for run()) */
1630
+ waitUntilExit(): Promise<void>;
1631
+ /**
1632
+ * Drain additional commit / layout cycles until layout reports stable
1633
+ * (no node dirty, no pending React commit) OR a budget cap is reached
1634
+ * (default 20 passes / 50ms wall clock).
1635
+ *
1636
+ * The default test harness exposes the post-`MAX_CONVERGENCE_PASSES`
1637
+ * frame — matching what production silvery commits on first paint.
1638
+ * Most tests don't need to wait further: keyboard / mouse input each
1639
+ * runs its own bounded-convergence loop, so an assertion after `press()`
1640
+ * already sees post-convergence state for that batch.
1641
+ *
1642
+ * This method is for assertions on layout state IMMEDIATELY after mount
1643
+ * that require chains needing more than `MAX_CONVERGENCE_PASSES` passes
1644
+ * to settle (rare with the layout-signals primitive, common with older
1645
+ * useState+onLayout chains). Returns once stable so tests can assert
1646
+ * post-convergence text/layout.
1647
+ *
1648
+ * Resolves without throwing even when the cap is hit — an infinitely
1649
+ * non-converging app is a structural bug surfaced by SILVERY_STRICT's
1650
+ * `assertBoundedConvergence`, not a test-author concern here.
1651
+ *
1652
+ * Bead: `@km/silvery/test-harness-convergence-cap-parity`.
1653
+ */
1654
+ waitForLayoutStable(opts?: {
1655
+ timeoutMs?: number;
1656
+ maxPasses?: number;
1657
+ }): Promise<void>;
1658
+ /**
1659
+ * Begin a CLS capture window. Layout shifts that occur between this call
1660
+ * and the next `endCLSCapture()` are recorded with the supplied
1661
+ * `ReasonClassifier` (default: every shift labeled "unexpected"). Use
1662
+ * `waitForLayoutStable()` to drain pending layout passes before reading
1663
+ * the report.
1664
+ *
1665
+ * Throws if a capture is already active — call `endCLSCapture()` or
1666
+ * `cancelCLSCapture()` first. The capture is process-wide (single active
1667
+ * recorder per process); two parallel captures on different App
1668
+ * instances is not supported by design.
1669
+ *
1670
+ * Bead: km-silvery.cls-instrumentation-primitive
1671
+ */
1672
+ beginCLSCapture(classifier?: ReasonClassifier): void;
1673
+ /**
1674
+ * End the active CLS capture and return the aggregated report. When
1675
+ * `SILVERY_STRICT=cls` (or tier 2+) is enabled, throws
1676
+ * `UnexpectedLayoutShiftError` if any shift has reflowReason="unexpected"
1677
+ * — failing-fast under STRICT lets close-gate tests skip explicit
1678
+ * assertions and rely on the umbrella env var.
1679
+ *
1680
+ * Throws if no capture is active.
1681
+ *
1682
+ * Bead: km-silvery.cls-instrumentation-primitive
1683
+ */
1684
+ endCLSCapture(): CLSReport;
1685
+ /**
1686
+ * Cancel the active CLS capture without producing a report. Idempotent
1687
+ * — safe to call when no capture is active. Used by test-cleanup paths
1688
+ * that need to bail without asserting.
1689
+ *
1690
+ * Bead: km-silvery.cls-instrumentation-primitive
1691
+ */
1692
+ cancelCLSCapture(): void;
1693
+ /** Clear the terminal output */
1694
+ clear(): void;
1695
+ /** Render current buffer to PNG. Requires Playwright (lazy-loaded on first call). */
1696
+ screenshot(outputPath?: string): Promise<Buffer>;
1697
+ /** Print component tree to console */
1698
+ debug(): void;
1699
+ /** Render the current tree from scratch (no incremental buffer reuse).
1700
+ * Returns the fresh buffer without updating incremental state.
1701
+ * Only available in test renderer - throws otherwise. */
1702
+ freshRender(): TerminalBuffer;
1703
+ /** Check if exit() was called */
1704
+ exitCalled(): boolean;
1705
+ /** Get error passed to exit() */
1706
+ exitError(): Error | undefined;
1707
+ /** Send raw stdin input (for sync test helpers; prefer app.press() for new code) */
1708
+ readonly stdin: {
1709
+ write: (data: string) => void;
1710
+ };
1711
+ /** All rendered frames (internal) */
1712
+ readonly frames: string[];
1713
+ /** Get last frame with ANSI codes (internal - use app.ansi instead) */
1714
+ lastFrame(): string | undefined;
1715
+ /** Get last buffer (internal - use app.term.buffer instead) */
1716
+ lastBuffer(): TerminalBuffer | undefined;
1717
+ /** Get last frame as plain text (internal - use app.text instead) */
1718
+ lastFrameText(): string | undefined;
1719
+ /** Get container root node (internal - use app.locator() instead) */
1720
+ getContainer(): AgNode;
1721
+ /** Focus a node by testID */
1722
+ focus(testID: string): void;
1723
+ /** Get the focus path from focused node to root (testID[]) */
1724
+ getFocusPath(): string[];
1725
+ /** Direct access to the FocusManager instance */
1726
+ readonly focusManager: FocusManager;
1727
+ /** Get the current cursor state for this silvery instance (per-instance, not global). */
1728
+ getCursorState(): CursorState | null;
1729
+ /**
1730
+ * Return the parent chain from the container root down to the first
1731
+ * AgNode whose component name matches `componentName`. Empty array if
1732
+ * not found. Useful for asserting structural invariants in tests and
1733
+ * for bead-investigation static traces ("does ToolBlock actually
1734
+ * render inside Content.Body[width=full]?").
1735
+ *
1736
+ * See `@silvery/ag-react/debug/render-path` for the underlying API.
1737
+ */
1738
+ renderPath(componentName: string): RenderPathNode[];
1739
+ /**
1740
+ * Recursive JSON dump of the entire mount tree. Useful for snapshot
1741
+ * tests asserting on structural invariants.
1742
+ */
1743
+ mountTree(): MountTree;
1744
+ }
1745
+ //#endregion
1746
+ //#region packages/ag-term/src/layout-engine.d.ts
1747
+ /**
1748
+ * Branded types prevent accidentally mixing up layout constant categories.
1749
+ * E.g., you can't pass an AlignValue where a FlexDirectionValue is expected.
1750
+ */
1751
+ type FlexDirectionValue = number & {
1752
+ readonly __brand: "FlexDirection";
1753
+ };
1754
+ type WrapValue = number & {
1755
+ readonly __brand: "Wrap";
1756
+ };
1757
+ type AlignValue = number & {
1758
+ readonly __brand: "Align";
1759
+ };
1760
+ type JustifyValue = number & {
1761
+ readonly __brand: "Justify";
1762
+ };
1763
+ type EdgeValue = number & {
1764
+ readonly __brand: "Edge";
1765
+ };
1766
+ type GutterValue = number & {
1767
+ readonly __brand: "Gutter";
1768
+ };
1769
+ type DisplayValue = number & {
1770
+ readonly __brand: "Display";
1771
+ };
1772
+ type PositionTypeValue = number & {
1773
+ readonly __brand: "PositionType";
1774
+ };
1775
+ type OverflowValue = number & {
1776
+ readonly __brand: "Overflow";
1777
+ };
1778
+ type DirectionValue = number & {
1779
+ readonly __brand: "Direction";
1780
+ };
1781
+ type MeasureModeValue = number & {
1782
+ readonly __brand: "MeasureMode";
1783
+ };
1784
+ /**
1785
+ * Constants for layout configuration.
1786
+ * These are the same across Yoga and Flexily.
1787
+ * Uses branded types for compile-time safety.
1788
+ */
1789
+ interface LayoutConstants {
1790
+ FLEX_DIRECTION_COLUMN: FlexDirectionValue;
1791
+ FLEX_DIRECTION_COLUMN_REVERSE: FlexDirectionValue;
1792
+ FLEX_DIRECTION_ROW: FlexDirectionValue;
1793
+ FLEX_DIRECTION_ROW_REVERSE: FlexDirectionValue;
1794
+ WRAP_NO_WRAP: WrapValue;
1795
+ WRAP_WRAP: WrapValue;
1796
+ WRAP_WRAP_REVERSE: WrapValue;
1797
+ ALIGN_AUTO: AlignValue;
1798
+ ALIGN_FLEX_START: AlignValue;
1799
+ ALIGN_CENTER: AlignValue;
1800
+ ALIGN_FLEX_END: AlignValue;
1801
+ ALIGN_STRETCH: AlignValue;
1802
+ ALIGN_BASELINE: AlignValue;
1803
+ ALIGN_SPACE_BETWEEN: AlignValue;
1804
+ ALIGN_SPACE_AROUND: AlignValue;
1805
+ ALIGN_SPACE_EVENLY: AlignValue;
1806
+ JUSTIFY_FLEX_START: JustifyValue;
1807
+ JUSTIFY_CENTER: JustifyValue;
1808
+ JUSTIFY_FLEX_END: JustifyValue;
1809
+ JUSTIFY_SPACE_BETWEEN: JustifyValue;
1810
+ JUSTIFY_SPACE_AROUND: JustifyValue;
1811
+ JUSTIFY_SPACE_EVENLY: JustifyValue;
1812
+ EDGE_LEFT: EdgeValue;
1813
+ EDGE_TOP: EdgeValue;
1814
+ EDGE_RIGHT: EdgeValue;
1815
+ EDGE_BOTTOM: EdgeValue;
1816
+ EDGE_HORIZONTAL: EdgeValue;
1817
+ EDGE_VERTICAL: EdgeValue;
1818
+ EDGE_ALL: EdgeValue;
1819
+ GUTTER_COLUMN: GutterValue;
1820
+ GUTTER_ROW: GutterValue;
1821
+ GUTTER_ALL: GutterValue;
1822
+ DISPLAY_FLEX: DisplayValue;
1823
+ DISPLAY_NONE: DisplayValue;
1824
+ POSITION_TYPE_STATIC: PositionTypeValue;
1825
+ POSITION_TYPE_RELATIVE: PositionTypeValue;
1826
+ POSITION_TYPE_ABSOLUTE: PositionTypeValue;
1827
+ OVERFLOW_VISIBLE: OverflowValue;
1828
+ OVERFLOW_HIDDEN: OverflowValue;
1829
+ OVERFLOW_SCROLL: OverflowValue;
1830
+ DIRECTION_LTR: DirectionValue;
1831
+ MEASURE_MODE_UNDEFINED: MeasureModeValue;
1832
+ MEASURE_MODE_EXACTLY: MeasureModeValue;
1833
+ MEASURE_MODE_AT_MOST: MeasureModeValue;
1834
+ }
1835
+ /**
1836
+ * Declares which engine-native primitives a `LayoutEngine` supports.
1837
+ *
1838
+ * silvery is engine-pluggable — `flexily` (pure JS) and `yoga` (WASM) ship as peer
1839
+ * adapters. The responsive-layout reframe (Phase A0.1+) adds engine-native container
1840
+ * queries, fitWidth, size containment, cq* units, and CSS math functions. These
1841
+ * primitives can only be implemented in `flexily` (yoga's WASM boundary doesn't expose
1842
+ * inter-pass child-style mutation).
1843
+ *
1844
+ * Each adapter declares which capabilities it supports. Consumers (`<Box fitWidth>`,
1845
+ * `<Box containerQueries>`, etc.) gate on capability presence via `requireCapability()`
1846
+ * — under yoga, those primitives THROW at first paint with a one-line fix instruction
1847
+ * (switch via `SILVERY_ENGINE=flexily`).
1848
+ */
1849
+ interface EngineCapabilities {
1850
+ /** Container queries: `<Box containerQueries={...}>` + `containerType` / `containerName` */
1851
+ readonly containerQueries: boolean;
1852
+ /** Size containment: `<Box containSize>` */
1853
+ readonly containSize: boolean;
1854
+ /** Container-query units in style values: `cqi`, `cqmin`, `cqb`, `cqmax` */
1855
+ readonly containerQueryUnits: boolean;
1856
+ /** fitWidth Box prop: `<Box fitWidth={[80, 120, "100cqi"]}>` */
1857
+ readonly fitWidth: boolean;
1858
+ /** CSS math functions in style values: `min()`, `max()`, `clamp()` */
1859
+ readonly styleMathFunctions: boolean;
1860
+ /** Inter-pass child-style mutation hook (underlying mechanism for CQ + fitWidth) */
1861
+ readonly childStyleMutation: boolean;
1862
+ }
1863
+ /**
1864
+ * Abstract layout engine interface.
1865
+ * Implementations can wrap Yoga, Flexily, or other layout engines.
1866
+ */
1867
+ interface LayoutEngine {
1868
+ /** Create a new layout node */
1869
+ createNode(): LayoutNode$1;
1870
+ /** Layout constants for this engine */
1871
+ readonly constants: LayoutConstants;
1872
+ /** Engine name for debugging */
1873
+ readonly name: string;
1874
+ /** Which engine-native primitives this adapter supports (Phase A0.0.5+). */
1875
+ readonly capabilities: EngineCapabilities;
1876
+ }
1877
+ /**
1878
+ * Set the global layout engine instance.
1879
+ * Must be called before rendering.
1880
+ */
1881
+ declare function setLayoutEngine(engine: LayoutEngine): void;
1882
+ /**
1883
+ * Check if a layout engine is initialized.
1884
+ */
1885
+ declare function isLayoutEngineInitialized(): boolean;
1886
+ /**
1887
+ * Layout engine type for configuration.
1888
+ *
1889
+ * - 'flexily': Zero-allocation Flexily (default, optimized for high-frequency layout)
1890
+ * - 'flexily-classic': Classic Flexily algorithm (for debugging/compatibility)
1891
+ * - 'yoga': Facebook's WASM-based flexbox (most mature)
1892
+ */
1893
+ type LayoutEngineType = "flexily" | "yoga";
1894
+ //#endregion
1895
+ //#region packages/ag-term/src/adapters/canvas-adapter.d.ts
1896
+ interface CanvasAdapterConfig {
1897
+ /** Font size in pixels (default: 14) */
1898
+ fontSize?: number;
1899
+ /** Font family (default: 'monospace') */
1900
+ fontFamily?: string;
1901
+ /** Line height multiplier (default: 1.2) */
1902
+ lineHeight?: number;
1903
+ /** Background color (default: '#1e1e1e') */
1904
+ backgroundColor?: string;
1905
+ /** Default foreground color (default: '#d4d4d4') */
1906
+ foregroundColor?: string;
1907
+ /** Monospace mode (default: true). When false, uses proportional font measurement. */
1908
+ monospace?: boolean;
1909
+ /** Device pixel ratio for sharp rendering on HiDPI displays (default: 1) */
1910
+ dpr?: number;
1911
+ }
1912
+ declare class CanvasRenderBuffer implements RenderBuffer {
1913
+ readonly width: number;
1914
+ readonly height: number;
1915
+ readonly canvas: OffscreenCanvas | HTMLCanvasElement;
1916
+ private ctx;
1917
+ private config;
1918
+ private readonly charWidth;
1919
+ private readonly cellHeight;
1920
+ constructor(width: number, height: number, config: Required<CanvasAdapterConfig>);
1921
+ fillRect(x: number, y: number, width: number, height: number, style: RenderStyle): void;
1922
+ drawText(x: number, y: number, text: string, style: RenderStyle): void;
1923
+ /**
1924
+ * Draw underline decorations at pixel coordinates.
1925
+ * Note: px, py are already in pixel coordinates.
1926
+ */
1927
+ private drawUnderline;
1928
+ drawChar(x: number, y: number, char: string, style: RenderStyle): void;
1929
+ inBounds(x: number, y: number): boolean;
1930
+ fillRoundedRect(x: number, y: number, width: number, height: number, radius: number, fill: string | undefined, stroke: string | undefined, lineWidth?: number): void;
1931
+ }
1932
+ declare function createCanvasAdapter(config?: CanvasAdapterConfig): RenderAdapter;
1933
+ //#endregion
1934
+ //#region packages/ag-term/src/adapters/dom-adapter.d.ts
1935
+ interface DOMAdapterConfig {
1936
+ /** Font size in pixels (default: 14) */
1937
+ fontSize?: number;
1938
+ /** Font family (default: 'monospace') */
1939
+ fontFamily?: string;
1940
+ /** Line height multiplier (default: 1.2) */
1941
+ lineHeight?: number;
1942
+ /** Background color (default: '#1e1e1e') */
1943
+ backgroundColor?: string;
1944
+ /** Default foreground color (default: '#d4d4d4') */
1945
+ foregroundColor?: string;
1946
+ /** CSS class prefix (default: 'silvery') */
1947
+ classPrefix?: string;
1948
+ }
1949
+ declare class DOMRenderBuffer implements RenderBuffer {
1950
+ readonly width: number;
1951
+ readonly height: number;
1952
+ private config;
1953
+ private lines;
1954
+ private backgrounds;
1955
+ private readonly charWidth;
1956
+ private readonly cellHeight;
1957
+ private container;
1958
+ constructor(width: number, height: number, config: Required<DOMAdapterConfig>);
1959
+ /**
1960
+ * Set the container element for rendering.
1961
+ */
1962
+ setContainer(container: HTMLElement): void;
1963
+ /**
1964
+ * Get the container element.
1965
+ */
1966
+ getContainer(): HTMLElement | null;
1967
+ fillRect(x: number, y: number, width: number, height: number, style: RenderStyle): void;
1968
+ drawText(x: number, y: number, text: string, style: RenderStyle): void;
1969
+ drawChar(x: number, y: number, char: string, style: RenderStyle): void;
1970
+ inBounds(x: number, y: number): boolean;
1971
+ /**
1972
+ * Render the buffer to the container element.
1973
+ * Coordinates in the buffer are in cell units (cols/rows).
1974
+ * This method converts them to pixel coordinates for DOM positioning.
1975
+ */
1976
+ render(): void;
1977
+ /**
1978
+ * Clear the buffer.
1979
+ */
1980
+ clear(): void;
1981
+ }
1982
+ declare function createDOMAdapter(config?: DOMAdapterConfig): RenderAdapter;
1983
+ /**
1984
+ * Inject global CSS styles for silvery DOM rendering.
1985
+ * Call once at application startup if you want default styling.
1986
+ */
1987
+ declare function injectDOMStyles(classPrefix?: string): void;
1988
+ //#endregion
1989
+ //#region packages/ag-term/src/bracketed-paste.d.ts
1990
+ /**
1991
+ * Bracketed Paste Mode
1992
+ *
1993
+ * Enables bracketed paste so the terminal wraps pasted text with markers.
1994
+ * This lets the app distinguish pasted text from typed input and receive
1995
+ * it as a single event rather than individual keystrokes.
1996
+ *
1997
+ * Protocol: DEC private mode 2004
1998
+ * - Enable: CSI ? 2004 h
1999
+ * - Disable: CSI ? 2004 l
2000
+ * - Paste start marker: CSI 200 ~
2001
+ * - Paste end marker: CSI 201 ~
2002
+ *
2003
+ * Supported by: Ghostty, Kitty, WezTerm, iTerm2, Alacritty, xterm, tmux, foot
2004
+ */
2005
+ /** Escape sequence that marks the beginning of pasted text */
2006
+ declare const PASTE_START = "\u001B[200~";
2007
+ /** Escape sequence that marks the end of pasted text */
2008
+ declare const PASTE_END = "\u001B[201~";
2009
+ /**
2010
+ * Enable bracketed paste mode.
2011
+ * Writes CSI ? 2004 h to the output stream.
2012
+ */
2013
+ declare function enableBracketedPaste(stdout: NodeJS.WriteStream): void;
2014
+ /**
2015
+ * Disable bracketed paste mode.
2016
+ * Writes CSI ? 2004 l to the output stream.
2017
+ */
2018
+ declare function disableBracketedPaste(stdout: NodeJS.WriteStream): void;
2019
+ /** Result of parsing a bracketed paste sequence */
2020
+ interface BracketedPasteResult {
2021
+ type: "paste";
2022
+ content: string;
2023
+ }
2024
+ /**
2025
+ * Detect and extract bracketed paste content from raw terminal input.
2026
+ *
2027
+ * Return semantics (see {@link ProtocolError} for the full contract):
2028
+ * - `null` — input contains no PASTE_START marker (this is not bracketed
2029
+ * paste input). Discriminator-chain "next parser please" signal.
2030
+ * - `throw ProtocolError` — input HAS PASTE_START (we committed to
2031
+ * bracketed paste) but no PASTE_END follows. This indicates either a
2032
+ * stream-split paste (caller should buffer and retry on the next chunk)
2033
+ * or a protocol violation. Loud failure surfaces the gap; the dispatch
2034
+ * layer catches and decides whether to buffer or log.
2035
+ */
2036
+ declare function parseBracketedPaste(input: string): BracketedPasteResult | null;
2037
+ //#endregion
2038
+ //#region packages/ag-term/src/osc-markers.d.ts
2039
+ /**
2040
+ * OSC 133 Semantic Prompt Markers
2041
+ *
2042
+ * Shell integration protocol that marks prompts and commands in terminal output.
2043
+ * Terminals like iTerm2, Kitty, and WezTerm use these markers to provide
2044
+ * "jump to previous/next prompt" navigation (Cmd+Up/Cmd+Down in iTerm2).
2045
+ *
2046
+ * Protocol: OSC 133
2047
+ * - Prompt start: ESC ] 133 ; A BEL (before user input)
2048
+ * - Prompt end: ESC ] 133 ; B BEL (after user input, before command output)
2049
+ * - Command output start: ESC ] 133 ; C BEL (before command output)
2050
+ * - Command output end: ESC ] 133 ; D ; N BEL (after command output, N = exit code)
2051
+ *
2052
+ * For a chat-style app, each "exchange" (user prompt + assistant response) maps to:
2053
+ * - 133;A before the user's message
2054
+ * - 133;B after the user's message
2055
+ * - 133;C before the assistant's response
2056
+ * - 133;D;0 after the assistant's response
2057
+ *
2058
+ * Supported by: iTerm2, Kitty, WezTerm, foot, Ghostty
2059
+ */
2060
+ declare const OSC133: {
2061
+ /** Mark prompt start (before user input) */readonly promptStart: "\u001B]133;A\u0007"; /** Mark prompt end (after user input, before command output) */
2062
+ readonly promptEnd: "\u001B]133;B\u0007"; /** Mark command output start */
2063
+ readonly commandStart: "\u001B]133;C\u0007"; /** Mark command output end (exit code defaults to 0 = success) */
2064
+ readonly commandEnd: (exitCode?: number) => string;
2065
+ };
2066
+ //#endregion
2067
+ //#region packages/ag-term/src/kitty-detect.d.ts
2068
+ interface KittyDetectResult {
2069
+ /** Whether the terminal responded to the Kitty protocol query */
2070
+ supported: boolean;
2071
+ /** Bitfield of KittyFlags the terminal reported supporting (0 if unsupported) */
2072
+ flags: number;
2073
+ /** Any non-response data that was read during detection (regular input that arrived) */
2074
+ buffered?: string;
2075
+ }
2076
+ /**
2077
+ * Detect Kitty keyboard protocol support.
2078
+ *
2079
+ * Sends CSI ? u to the terminal and waits for a response.
2080
+ * Supported terminals respond with CSI ? flags u.
2081
+ * Unsupported terminals either ignore the query or echo it.
2082
+ *
2083
+ * @param write Function to write to stdout
2084
+ * @param read Function to read a chunk from stdin (should resolve with data or null on timeout)
2085
+ * @param timeoutMs How long to wait for response (default: 200ms)
2086
+ */
2087
+ declare function detectKittySupport(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<KittyDetectResult>;
2088
+ /**
2089
+ * Detect Kitty support using real stdin/stdout.
2090
+ * Convenience wrapper around detectKittySupport.
2091
+ */
2092
+ declare function detectKittyFromStdio(stdout: {
2093
+ write: (s: string) => boolean | void;
2094
+ }, stdin: NodeJS.ReadStream, timeoutMs?: number): Promise<KittyDetectResult>;
2095
+ //#endregion
2096
+ //#region packages/ag-term/src/termtest.d.ts
2097
+ /**
2098
+ * Terminal Capability Test
2099
+ *
2100
+ * Renders labeled test patterns for each terminal feature.
2101
+ * Run in any terminal to visually verify what it supports.
2102
+ *
2103
+ * Usage:
2104
+ * import { runTermtest } from "@silvery/ag-react"
2105
+ * runTermtest() // all sections
2106
+ * runTermtest({ sections: ["emoji", "colors"] }) // specific sections
2107
+ *
2108
+ * Compare output across terminals to build/verify profiles.
2109
+ */
2110
+ /** Available test sections */
2111
+ declare const TERMTEST_SECTIONS: readonly ["sgr", "underline", "colors", "256", "truecolor", "unicode", "emoji", "borders", "inverse", "profile"];
2112
+ type TermtestSection = (typeof TERMTEST_SECTIONS)[number];
2113
+ interface TermtestOptions {
2114
+ /** Writable stream (defaults to process.stdout) */
2115
+ output?: {
2116
+ write(s: string): boolean;
2117
+ };
2118
+ /** Show only these sections. Omit or empty = all sections. */
2119
+ sections?: TermtestSection[];
2120
+ }
2121
+ /**
2122
+ * Run the terminal capability test.
2123
+ * Pass section names to filter: `runTermtest({ sections: ["emoji"] })`
2124
+ */
2125
+ declare function runTermtest(options?: TermtestOptions): void;
2126
+ //#endregion
2127
+ //#region packages/ag-term/src/text-sizing.d.ts
2128
+ /**
2129
+ * Text Sizing Protocol (OSC 66) -- Kitty v0.40+
2130
+ *
2131
+ * Lets the app specify how many cells a character should occupy.
2132
+ * This solves the measurement/rendering mismatch for Private Use Area (PUA)
2133
+ * characters (nerdfont icons, powerline symbols) that `string-width` reports
2134
+ * as 1-cell but terminals render as 2-cell.
2135
+ *
2136
+ * When OSC 66 is used with w=2, both the app's layout engine and the terminal
2137
+ * agree on the character width, eliminating truncation and misalignment.
2138
+ *
2139
+ * Protocol format:
2140
+ * ESC ] 66 ; w=<width> ; <text> BEL
2141
+ *
2142
+ * Post km-silvery.unicode-plateau Phase 2 (2026-04-23): this module reads
2143
+ * ZERO environment variables. Capability detection lives entirely in
2144
+ * `@silvery/ansi`'s `createTerminalProfile`. Consumers pass `TerminalCaps`
2145
+ * (or an explicit fingerprint string for the probe cache) so the module is
2146
+ * pure w.r.t. environment and browser/canvas targets aren't broken.
2147
+ *
2148
+ * @see https://sw.kovidgoyal.net/kitty/text-sizing-protocol/
2149
+ */
2150
+ /**
2151
+ * Wrap text in an OSC 66 sequence that tells the terminal to render it
2152
+ * in exactly `width` cells.
2153
+ */
2154
+ declare function textSized(text: string, width: number): string;
2155
+ /**
2156
+ * Check if a code point is in the Private Use Area (PUA).
2157
+ * Covers BMP PUA (U+E000-U+F8FF) and Supplementary PUA-A/B.
2158
+ */
2159
+ declare function isPrivateUseArea(cp: number): boolean;
2160
+ /**
2161
+ * Structural subset of the terminal profile's emulator the fingerprint helper
2162
+ * needs. Accepts any object with `program` + `version` strings (typically
2163
+ * `profile.emulator` or `term.emulator`).
2164
+ */
2165
+ interface FingerprintEmulator {
2166
+ readonly program: string;
2167
+ readonly version: string;
2168
+ }
2169
+ /**
2170
+ * Build a terminal fingerprint for cache keying. Combines `program` +
2171
+ * `version` from the supplied emulator to uniquely identify the terminal
2172
+ * type. Different versions may add/remove OSC 66 support, so version is part
2173
+ * of the key.
2174
+ *
2175
+ * Post unicode-plateau Phase 2: the emulator argument is required — the
2176
+ * legacy env-reading variant is gone. Callers building fingerprints from a
2177
+ * one-shot probe can use `createTerminalProfile().emulator` upstream.
2178
+ */
2179
+ declare function getTerminalFingerprint(emulator: FingerprintEmulator): string;
2180
+ /** Result of text sizing probe */
2181
+ interface TextSizingProbeResult {
2182
+ supported: boolean;
2183
+ widthOnly: boolean;
2184
+ }
2185
+ /**
2186
+ * Detect terminal support for the text sizing protocol.
2187
+ * Uses cursor position reports (CPR) to check if OSC 66 advances the cursor
2188
+ * by the specified width.
2189
+ *
2190
+ * Results are cached by fingerprint so the probe only runs once per terminal
2191
+ * type per process.
2192
+ *
2193
+ * @param write - Writer function (TUI output)
2194
+ * @param read - Reader function (CPR response source)
2195
+ * @param fingerprint - Cache key. Derived via {@link getTerminalFingerprint}
2196
+ * from `TerminalCaps`; callers inside a running session typically compute
2197
+ * it once from `term.profile.caps`.
2198
+ * @param timeout - Per-probe timeout in ms (default 1000)
2199
+ * @returns Object with `supported` and `widthOnly` flags:
2200
+ * - supported=true, widthOnly=false: full support (scale + width)
2201
+ * - supported=true, widthOnly=true: width mode only
2202
+ * - supported=false: no support
2203
+ */
2204
+ declare function detectTextSizingSupport(write: (data: string) => void, read: () => Promise<string>, fingerprint: string, timeout?: number): Promise<TextSizingProbeResult>;
2205
+ //#endregion
2206
+ //#region packages/ag-term/src/cursor-query.d.ts
2207
+ /**
2208
+ * CSI 6n Cursor Position Query
2209
+ *
2210
+ * Queries the terminal for the current cursor position using the standard
2211
+ * Device Status Report (DSR) mechanism.
2212
+ *
2213
+ * Protocol:
2214
+ * - Query: CSI 6 n (\x1b[6n)
2215
+ * - Response: CSI {row} ; {col} R (\x1b[{row};{col}R)
2216
+ *
2217
+ * Row and column are 1-indexed in the protocol response.
2218
+ *
2219
+ * Supported by: virtually all terminals (VT100+)
2220
+ */
2221
+ /**
2222
+ * Query the terminal cursor position.
2223
+ *
2224
+ * Sends CSI 6n and parses the CPR response.
2225
+ * Returns 1-indexed row and column.
2226
+ *
2227
+ * @param write Function to write to stdout
2228
+ * @param read Function to read a chunk from stdin (resolves with data or null on timeout)
2229
+ * @param timeoutMs How long to wait for response (default: 200ms)
2230
+ */
2231
+ declare function queryCursorPosition(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2232
+ row: number;
2233
+ col: number;
2234
+ } | null>;
2235
+ /**
2236
+ * Query cursor position using real stdin/stdout.
2237
+ * Convenience wrapper around queryCursorPosition.
2238
+ */
2239
+ declare function queryCursorFromStdio(stdout: {
2240
+ write: (s: string) => boolean | void;
2241
+ }, stdin: NodeJS.ReadStream, timeoutMs?: number): Promise<{
2242
+ row: number;
2243
+ col: number;
2244
+ } | null>;
2245
+ //#endregion
2246
+ //#region packages/ag-term/src/device-attrs.d.ts
2247
+ /**
2248
+ * Device Attributes (DA1/DA2/DA3) + XTVERSION Queries
2249
+ *
2250
+ * Provides functions to query terminal identity and capabilities using
2251
+ * the standard VT device attribute escape sequences.
2252
+ *
2253
+ * Protocols:
2254
+ *
2255
+ * DA1 (Primary Device Attributes):
2256
+ * Query: CSI c (\x1b[c)
2257
+ * Response: CSI ? Ps ; Ps ; ... c
2258
+ *
2259
+ * DA2 (Secondary Device Attributes):
2260
+ * Query: CSI > c (\x1b[>c)
2261
+ * Response: CSI > Pt ; Pv ; Pc c
2262
+ * Where Pt=terminal type, Pv=firmware version, Pc=ROM cartridge id
2263
+ *
2264
+ * DA3 (Tertiary Device Attributes):
2265
+ * Query: CSI = c (\x1b[=c)
2266
+ * Response: DCS ! | hex-encoded-id ST (\x1bP!|{hex}\x1b\\)
2267
+ *
2268
+ * XTVERSION (Terminal Name + Version):
2269
+ * Query: CSI > 0 q (\x1b[>0q)
2270
+ * Response: DCS > | name(version) ST (\x1bP>|{text}\x1b\\)
2271
+ *
2272
+ * Supported by: xterm, Ghostty, Kitty, WezTerm, foot, VTE-based terminals
2273
+ */
2274
+ /**
2275
+ * Query primary device attributes (DA1).
2276
+ *
2277
+ * Returns the list of attribute parameters the terminal reports.
2278
+ * Common params: 1=132-cols, 4=sixel, 6=selective-erase, 22=ANSI-color
2279
+ *
2280
+ * @param write Function to write to stdout
2281
+ * @param read Function to read a chunk from stdin
2282
+ * @param timeoutMs How long to wait for response (default: 200ms)
2283
+ */
2284
+ declare function queryPrimaryDA(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2285
+ params: number[];
2286
+ } | null>;
2287
+ /**
2288
+ * Query secondary device attributes (DA2).
2289
+ *
2290
+ * Returns terminal type, firmware version, and ROM cartridge id.
2291
+ * Common type values: 0=VT100, 1=VT220, 41=xterm, 65=VT500
2292
+ *
2293
+ * @param write Function to write to stdout
2294
+ * @param read Function to read a chunk from stdin
2295
+ * @param timeoutMs How long to wait for response (default: 200ms)
2296
+ */
2297
+ declare function querySecondaryDA(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2298
+ type: number;
2299
+ version: number;
2300
+ id: number;
2301
+ } | null>;
2302
+ /**
2303
+ * Query tertiary device attributes (DA3).
2304
+ *
2305
+ * Returns a hex-encoded unit ID string. Decode with Buffer.from(hex, 'hex').
2306
+ *
2307
+ * @param write Function to write to stdout
2308
+ * @param read Function to read a chunk from stdin
2309
+ * @param timeoutMs How long to wait for response (default: 200ms)
2310
+ */
2311
+ declare function queryTertiaryDA(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
2312
+ /**
2313
+ * Query the terminal name and version via XTVERSION.
2314
+ *
2315
+ * Returns the version string as reported by the terminal, e.g.:
2316
+ * - "xterm(388)"
2317
+ * - "tmux 3.4"
2318
+ * - "WezTerm 20230712-072601-f4abf8fd"
2319
+ *
2320
+ * @param write Function to write to stdout
2321
+ * @param read Function to read a chunk from stdin
2322
+ * @param timeoutMs How long to wait for response (default: 200ms)
2323
+ */
2324
+ declare function queryTerminalVersion(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
2325
+ /** Combined device attributes result. */
2326
+ interface DeviceAttributes {
2327
+ da1: {
2328
+ params: number[];
2329
+ } | null;
2330
+ da2: {
2331
+ type: number;
2332
+ version: number;
2333
+ id: number;
2334
+ } | null;
2335
+ version: string | null;
2336
+ }
2337
+ /**
2338
+ * Query all device attributes: DA1, DA2, and XTVERSION.
2339
+ *
2340
+ * Convenience wrapper that queries all three sequentially.
2341
+ * DA3 is omitted from the combined query as it's rarely needed.
2342
+ *
2343
+ * @param stdout Writable stream (e.g., process.stdout)
2344
+ * @param stdin Readable stream (e.g., process.stdin)
2345
+ * @param timeoutMs Per-query timeout (default: 200ms)
2346
+ */
2347
+ declare function queryDeviceAttributes(stdout: {
2348
+ write: (s: string) => boolean | void;
2349
+ }, stdin: NodeJS.ReadStream, timeoutMs?: number): Promise<DeviceAttributes>;
2350
+ //#endregion
2351
+ //#region packages/ag-term/src/focus-reporting.d.ts
2352
+ /**
2353
+ * Focus Reporting (CSI ?1004h)
2354
+ *
2355
+ * Enables/disables terminal focus-in/focus-out event reporting.
2356
+ * When enabled, the terminal sends CSI I on focus-in and CSI O on focus-out.
2357
+ *
2358
+ * Protocol:
2359
+ * - Enable: CSI ? 1004 h
2360
+ * - Disable: CSI ? 1004 l
2361
+ * - Focus In: CSI I (\x1b[I)
2362
+ * - Focus Out: CSI O (\x1b[O)
2363
+ *
2364
+ * Supported by: xterm (v282+), Ghostty, Kitty, WezTerm, iTerm2, foot, VTE
2365
+ */
2366
+ /**
2367
+ * Enable terminal focus reporting.
2368
+ * After enabling, the terminal will send CSI I / CSI O sequences
2369
+ * when the terminal window gains or loses focus.
2370
+ */
2371
+ declare function enableFocusReporting(write: (data: string) => void): void;
2372
+ /**
2373
+ * Disable terminal focus reporting.
2374
+ */
2375
+ declare function disableFocusReporting(write: (data: string) => void): void;
2376
+ /**
2377
+ * Parse a focus event from terminal input.
2378
+ *
2379
+ * Return semantics (see ProtocolError in @silvery/ansi for the full contract):
2380
+ * - `null` — input contains neither `CSI I` nor `CSI O` markers (not a
2381
+ * focus event). Discriminator-chain "next parser please" signal.
2382
+ *
2383
+ * The bead 15127 audit listed this parser for review, but there is no
2384
+ * "committed but malformed" branch — the marker either appears in the
2385
+ * input or it doesn't. No ProtocolError throw needed.
2386
+ *
2387
+ * @param input Raw terminal input string
2388
+ * @returns Parsed focus event, or null if not a focus sequence
2389
+ */
2390
+ declare function parseFocusEvent(input: string): {
2391
+ type: "focus-in" | "focus-out";
2392
+ } | null;
2393
+ //#endregion
2394
+ //#region packages/ag-term/src/mode-query.d.ts
2395
+ /**
2396
+ * DECRQM — DEC Private Mode Query
2397
+ *
2398
+ * Queries the terminal for the state of DEC private modes.
2399
+ *
2400
+ * Protocol:
2401
+ * - Query: CSI ? {mode} $ p
2402
+ * - Response: CSI ? {mode} ; {Ps} $ y
2403
+ *
2404
+ * Where Ps is:
2405
+ * 1 = set (mode is enabled)
2406
+ * 2 = reset (mode is disabled)
2407
+ * 0 = not recognized (unknown mode)
2408
+ * 3 = permanently set
2409
+ * 4 = permanently reset
2410
+ *
2411
+ * We normalize 3→"set" and 4→"reset" for simplicity.
2412
+ *
2413
+ * Supported by: xterm, Ghostty, Kitty, WezTerm, foot, VTE-based terminals
2414
+ */
2415
+ /** Well-known DEC private mode constants. */
2416
+ declare const DecMode: {
2417
+ /** DEC cursor visible (DECTCEM) */readonly CURSOR_VISIBLE: 25; /** Alternate screen buffer (DECSET 1049) */
2418
+ readonly ALT_SCREEN: 1049; /** Normal mouse tracking (X10) */
2419
+ readonly MOUSE_TRACKING: 1000; /** Bracketed paste mode */
2420
+ readonly BRACKETED_PASTE: 2004; /** Synchronized output */
2421
+ readonly SYNC_OUTPUT: 2026; /** Focus reporting */
2422
+ readonly FOCUS_REPORTING: 1004;
2423
+ };
2424
+ type ModeState = "set" | "reset" | "unknown";
2425
+ /**
2426
+ * Query the state of a single DEC private mode.
2427
+ *
2428
+ * @param write Function to write to stdout
2429
+ * @param read Function to read a chunk from stdin
2430
+ * @param mode DEC private mode number (e.g., DecMode.ALT_SCREEN)
2431
+ * @param timeoutMs How long to wait for response (default: 200ms)
2432
+ * @returns "set", "reset", or "unknown"
2433
+ */
2434
+ declare function queryMode(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, mode: number, timeoutMs?: number): Promise<ModeState>;
2435
+ /**
2436
+ * Query the state of multiple DEC private modes.
2437
+ *
2438
+ * Queries each mode sequentially and returns a Map of results.
2439
+ *
2440
+ * @param write Function to write to stdout
2441
+ * @param read Function to read a chunk from stdin
2442
+ * @param modes Array of DEC private mode numbers
2443
+ * @param timeoutMs Per-query timeout (default: 200ms)
2444
+ */
2445
+ declare function queryModes(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, modes: number[], timeoutMs?: number): Promise<Map<number, ModeState>>;
2446
+ //#endregion
2447
+ //#region packages/ag-term/src/pixel-size.d.ts
2448
+ /**
2449
+ * CSI 14t/18t — Terminal Pixel and Text Area Size Queries
2450
+ *
2451
+ * Queries the terminal for window dimensions in pixels and characters.
2452
+ *
2453
+ * Protocols:
2454
+ *
2455
+ * Text Area Pixels (CSI 14t):
2456
+ * Query: CSI 14 t
2457
+ * Response: CSI 4 ; height ; width t
2458
+ *
2459
+ * Text Area Size in Characters (CSI 18t):
2460
+ * Query: CSI 18 t
2461
+ * Response: CSI 8 ; rows ; cols t
2462
+ *
2463
+ * Cell size can be derived by dividing pixel dimensions by character dimensions.
2464
+ *
2465
+ * Supported by: xterm, Ghostty, Kitty, WezTerm, foot, iTerm2
2466
+ */
2467
+ /**
2468
+ * Query the terminal text area size in pixels.
2469
+ *
2470
+ * @param write Function to write to stdout
2471
+ * @param read Function to read a chunk from stdin
2472
+ * @param timeoutMs How long to wait for response (default: 200ms)
2473
+ * @returns Width and height in pixels, or null on timeout/unsupported
2474
+ */
2475
+ declare function queryTextAreaPixels(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2476
+ width: number;
2477
+ height: number;
2478
+ } | null>;
2479
+ /**
2480
+ * Query the terminal text area size in characters (rows x columns).
2481
+ *
2482
+ * @param write Function to write to stdout
2483
+ * @param read Function to read a chunk from stdin
2484
+ * @param timeoutMs How long to wait for response (default: 200ms)
2485
+ * @returns Rows and columns, or null on timeout/unsupported
2486
+ */
2487
+ declare function queryTextAreaSize(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2488
+ cols: number;
2489
+ rows: number;
2490
+ } | null>;
2491
+ /**
2492
+ * Query the terminal cell size in pixels by querying both pixel
2493
+ * dimensions and character dimensions, then dividing.
2494
+ *
2495
+ * @param write Function to write to stdout
2496
+ * @param read Function to read a chunk from stdin
2497
+ * @param timeoutMs Per-query timeout (default: 200ms)
2498
+ * @returns Cell width and height in pixels, or null if either query fails
2499
+ */
2500
+ declare function queryCellSize(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<{
2501
+ width: number;
2502
+ height: number;
2503
+ } | null>;
2504
+ //#endregion
2505
+ //#region packages/ag-term/src/term-def.d.ts
2506
+ /**
2507
+ * Minimal surface for configuring render().
2508
+ *
2509
+ * TermDef provides a simple way to configure rendering without requiring
2510
+ * a full Term instance. It's useful for:
2511
+ * - Static rendering (just width/height, no events)
2512
+ * - Testing (mock dimensions and events)
2513
+ * - Quick scripts (auto-detect everything from stdin/stdout)
2514
+ *
2515
+ * The presence of `events` (or `stdin` which auto-creates events)
2516
+ * determines the render mode:
2517
+ * - No events → static mode (render until stable)
2518
+ * - Has events → interactive mode (render until exit() called)
2519
+ *
2520
+ * @example
2521
+ * ```tsx
2522
+ * // Static render with custom width
2523
+ * const output = await render(<App />, { width: 100 })
2524
+ *
2525
+ * // Interactive with stdin/stdout
2526
+ * await render(<App />, { stdin: process.stdin, stdout: process.stdout })
2527
+ *
2528
+ * // Custom events
2529
+ * await render(<App />, { events: myEventSource })
2530
+ * ```
2531
+ */
2532
+ interface TermDef {
2533
+ /** Output stream (used for dimensions if not specified) */
2534
+ stdout?: NodeJS.WriteStream;
2535
+ /** Width in columns (default: stdout?.columns ?? 80) */
2536
+ width?: number;
2537
+ /** Height in rows (default: stdout?.rows ?? 24) */
2538
+ height?: number;
2539
+ /**
2540
+ * Color support (true=detect, false=mono, or specific {@link ColorLevel}).
2541
+ *
2542
+ * `null` is accepted as a compat alias for `"mono"` (pre-terminal-profile-plateau
2543
+ * no-color spelling).
2544
+ */
2545
+ colors?: boolean | ColorLevel | null;
2546
+ /**
2547
+ * Event source for interactive mode.
2548
+ *
2549
+ * When present, render runs until exit() is called.
2550
+ * When absent, render completes when UI is stable.
2551
+ */
2552
+ events?: AsyncIterable<Event> | EventSource;
2553
+ /**
2554
+ * Standard input stream.
2555
+ *
2556
+ * When provided (and events is not), automatically creates input events
2557
+ * from stdin, enabling interactive mode.
2558
+ */
2559
+ stdin?: NodeJS.ReadStream;
2560
+ }
2561
+ /**
2562
+ * Check if a value is a Term instance (duck typing).
2563
+ *
2564
+ * Post km-silvery.caps-restructure Phase 7: the legacy hasCursor/hasInput/
2565
+ * hasColor methods were removed — caps/profile/write/size are the canonical
2566
+ * Term surface.
2567
+ */
2568
+ declare function isTerm(value: unknown): value is Term;
2569
+ /**
2570
+ * Create an async iterable of input events from a stdin stream.
2571
+ *
2572
+ * This enables interactive mode by providing a source of keyboard events.
2573
+ */
2574
+ declare function createInputEvents(stdin: NodeJS.ReadStream): AsyncIterable<Event>;
2575
+ //#endregion
2576
+ //#region packages/ag-term/src/non-tty.d.ts
2577
+ /**
2578
+ * Non-TTY Mode Support for Silvery
2579
+ *
2580
+ * Provides detection and rendering modes for non-interactive environments:
2581
+ * - Piped output (process.stdout.isTTY === false)
2582
+ * - CI environments
2583
+ * - TERM=dumb
2584
+ *
2585
+ * When in non-TTY mode, silvery avoids cursor positioning codes that garble
2586
+ * output in non-interactive environments.
2587
+ *
2588
+ * Modes:
2589
+ * - 'auto': Detect based on environment (default)
2590
+ * - 'tty': Force TTY mode (normal cursor positioning)
2591
+ * - 'line-by-line': Simple newline-separated output, no cursor movement
2592
+ * - 'static': Single output at end (no updates)
2593
+ * - 'plain': Strip all ANSI codes
2594
+ */
2595
+ /**
2596
+ * Non-TTY rendering mode.
2597
+ *
2598
+ * - 'auto': Auto-detect based on environment
2599
+ * - 'tty': Force TTY mode with cursor positioning
2600
+ * - 'line-by-line': Output lines without cursor repositioning
2601
+ * - 'static': Single final output only
2602
+ * - 'plain': Strip all ANSI escape codes
2603
+ */
2604
+ type NonTTYMode = "auto" | "tty" | "line-by-line" | "static" | "plain";
2605
+ /**
2606
+ * Options for non-TTY output.
2607
+ */
2608
+ interface NonTTYOptions {
2609
+ /** The rendering mode. Default: 'auto' */
2610
+ mode?: NonTTYMode;
2611
+ /** Output stream to check for TTY status. Default: process.stdout */
2612
+ stdout?: NodeJS.WriteStream;
2613
+ }
2614
+ /**
2615
+ * Resolved non-TTY mode after auto-detection.
2616
+ */
2617
+ type ResolvedNonTTYMode = Exclude<NonTTYMode, "auto">;
2618
+ /**
2619
+ * Check if the environment is a TTY.
2620
+ *
2621
+ * Returns false if:
2622
+ * - stdout.isTTY is false or undefined
2623
+ * - TERM=dumb
2624
+ * - CI environment variables are set
2625
+ *
2626
+ * Pass `emulator` (from `term.emulator` or a TerminalEmulator fixture) when
2627
+ * available to avoid a redundant env read. Without it, the TERM=dumb check
2628
+ * delegates to {@link createTerminalProfile} — the canonical single-source-
2629
+ * of-truth entry in `@silvery/ansi/profile`. CI env vars remain read
2630
+ * directly because they are orthogonal to terminal capabilities (a CI
2631
+ * runner's TTY status doesn't describe what the terminal can render).
2632
+ */
2633
+ declare function isTTY(stdout?: NodeJS.WriteStream, /** Structural emulator — `{ TERM }` is the only field this helper reads. */
2634
+
2635
+ emulator?: {
2636
+ TERM: string;
2637
+ }): boolean;
2638
+ /**
2639
+ * Resolve the non-TTY mode based on options and environment.
2640
+ *
2641
+ * When mode is 'auto':
2642
+ * - If TTY detected: returns 'tty'
2643
+ * - If non-TTY detected: returns 'line-by-line'
2644
+ */
2645
+ declare function resolveNonTTYMode(options?: NonTTYOptions): ResolvedNonTTYMode;
2646
+ //#endregion
2647
+ //#region packages/ag-term/src/errors.d.ts
2648
+ /** Structured mismatch data attached to the error (mirrors MismatchDebugContext shape) */
2649
+ interface MismatchErrorData {
2650
+ /** Render-phase instrumentation snapshot (nodes visited/rendered/skipped, per-flag breakdown) */
2651
+ renderPhaseStats?: RenderPhaseStats;
2652
+ /** Debug context for the mismatched cell (from debug-mismatch.ts) */
2653
+ mismatchContext?: unknown;
2654
+ }
2655
+ /**
2656
+ * Error thrown when SILVERY_STRICT detects a mismatch.
2657
+ * This error should NOT be caught by general error handlers - it indicates
2658
+ * a bug in incremental rendering that needs to be fixed.
2659
+ *
2660
+ * When SILVERY_STRICT fires, the error automatically includes:
2661
+ * - Render-phase instrumentation (nodes visited/rendered/skipped, per-flag breakdown)
2662
+ * - Cell attribution (which node owns the mismatched cell, dirty flags, scroll context)
2663
+ */
2664
+ declare class IncrementalRenderMismatchError extends Error {
2665
+ /** Render-phase instrumentation snapshot */
2666
+ renderPhaseStats?: RenderPhaseStats;
2667
+ /** Debug context for the mismatched cell */
2668
+ mismatchContext?: unknown;
2669
+ constructor(message: string, data?: MismatchErrorData);
2670
+ }
2671
+ //#endregion
2672
+ //#region packages/ag-term/src/scheduler.d.ts
2673
+ interface RenderStats {
2674
+ /** Number of renders executed */
2675
+ renderCount: number;
2676
+ /** Number of renders skipped (batched) */
2677
+ skippedCount: number;
2678
+ /** Last render duration in ms */
2679
+ lastRenderTime: number;
2680
+ /** Average render time in ms */
2681
+ avgRenderTime: number;
2682
+ }
2683
+ //#endregion
2684
+ //#region packages/ag-term/src/inspector.d.ts
2685
+ interface InspectorOptions {
2686
+ /** Output stream (default: process.stderr) */
2687
+ output?: NodeJS.WritableStream;
2688
+ /** Log file path (overrides output stream) */
2689
+ logFile?: string;
2690
+ /** Include layout rects in tree dump */
2691
+ showLayout?: boolean;
2692
+ /** Include style info in tree dump */
2693
+ showStyles?: boolean;
2694
+ }
2695
+ /** Enable the silvery inspector. */
2696
+ declare function enableInspector(options?: InspectorOptions): void;
2697
+ /** Disable the inspector. */
2698
+ declare function disableInspector(): void;
2699
+ /** Check if inspector is active. */
2700
+ declare function isInspectorEnabled(): boolean;
2701
+ /**
2702
+ * Log render stats after each frame.
2703
+ *
2704
+ * Called by the scheduler after doRender completes. When the inspector
2705
+ * is disabled this is a no-op (zero overhead).
2706
+ */
2707
+ declare function inspectFrame(stats: RenderStats): void;
2708
+ /**
2709
+ * Dump the component tree structure as indented text.
2710
+ *
2711
+ * Walks the SilveryNode tree and formats each node with its type, testID,
2712
+ * layout rect, and dirty flags.
2713
+ */
2714
+ declare function inspectTree(rootNode: AgNode, options?: {
2715
+ depth?: number;
2716
+ showLayout?: boolean;
2717
+ }): string;
2718
+ /**
2719
+ * Auto-enable if SILVERY_DEV=1 is set.
2720
+ *
2721
+ * Call this at startup to respect the environment variable convention.
2722
+ */
2723
+ declare function autoEnableInspector(): void;
2724
+ //#endregion
2725
+ //#region packages/ag-term/src/measurer.d.ts
2726
+ /**
2727
+ * Term extended with measurement capabilities.
2728
+ */
2729
+ interface MeasuredTerm extends Term, Measurer {}
2730
+ /**
2731
+ * Extend a Term with measurement capabilities.
2732
+ *
2733
+ * Creates a width measurer from the term's caps and adds measurement
2734
+ * methods (displayWidth, graphemeWidth, wrapText, etc.) to the term.
2735
+ */
2736
+ declare function withMeasurer(term: Term): MeasuredTerm;
2737
+ /**
2738
+ * Create a pipeline configuration from caps and/or measurer.
2739
+ *
2740
+ * This is the single factory for PipelineConfig -- use it instead of
2741
+ * manually constructing { measurer, outputPhaseFn }.
2742
+ *
2743
+ * @param options.caps - Terminal capabilities (for output phase SGR generation).
2744
+ * Reads `caps.maybeWideEmojis` (text-presentation emoji width) and
2745
+ * `caps.textSizing` for measurement.
2746
+ * @param options.measurer - Explicit measurer (if omitted, created from caps)
2747
+ */
2748
+ declare function createPipeline(options?: {
2749
+ caps?: TerminalCaps;
2750
+ measurer?: Measurer;
2751
+ }): PipelineConfig;
2752
+ //#endregion
2753
+ //#region packages/ag-term/src/scroll-utils.d.ts
2754
+ /**
2755
+ * Scroll Utilities
2756
+ *
2757
+ * Shared functions for edge-based scrolling behavior across VirtualList,
2758
+ * HorizontalVirtualList, and other scroll-aware components.
2759
+ */
2760
+ /**
2761
+ * Calculate edge-based scroll offset.
2762
+ *
2763
+ * Only scrolls when cursor approaches the edge of the visible area.
2764
+ * This provides smoother scrolling by starting to scroll before hitting
2765
+ * the absolute edge, maintaining context around the selected item.
2766
+ *
2767
+ * ## Algorithm
2768
+ *
2769
+ * The viewport is divided into zones:
2770
+ * ```
2771
+ * |<padding>|<------ safe zone ------>|<padding>|
2772
+ * | scroll | no scroll needed | scroll |
2773
+ * | if < | | if > |
2774
+ * ```
2775
+ *
2776
+ * When the selected item enters a padding zone, the viewport scrolls
2777
+ * to keep the item visible with margin.
2778
+ *
2779
+ * ## Asymmetry Note
2780
+ *
2781
+ * The +1 in the "scroll down/right" case is intentional:
2782
+ * - Offset points to the TOP/LEFT of the viewport
2783
+ * - We want the selected item to be `padding` items from the BOTTOM/RIGHT
2784
+ * - Formula: `selectedIndex - visibleCount + padding + 1`
2785
+ *
2786
+ * Example: visibleCount=10, padding=2, selectedIndex=15
2787
+ * offset = 15 - 10 + 2 + 1 = 8
2788
+ * viewport shows items 8-17, selected item 15 is at position 7 (2 from bottom)
2789
+ *
2790
+ * @param selectedIndex - Currently selected item index
2791
+ * @param currentOffset - Current scroll offset (topmost/leftmost visible item)
2792
+ * @param visibleCount - Number of items visible in viewport
2793
+ * @param totalCount - Total number of items
2794
+ * @param padding - Items to keep visible before/after cursor (default: 1)
2795
+ * @returns New scroll offset
2796
+ */
2797
+ declare function calcEdgeBasedScrollOffset(selectedIndex: number, currentOffset: number, visibleCount: number, totalCount: number, padding?: number): number;
2798
+ //#endregion
2799
+ //#region packages/ag-term/src/scroll-region.d.ts
2800
+ /**
2801
+ * Terminal scroll region (DECSTBM) utilities.
2802
+ *
2803
+ * Scroll regions tell the terminal to natively scroll content within
2804
+ * a defined row range, which is faster than re-rendering all cells.
2805
+ *
2806
+ * DECSTBM (DEC Set Top and Bottom Margins) is supported by most modern
2807
+ * terminal emulators: xterm, iTerm2, Kitty, Ghostty, WezTerm, etc.
2808
+ */
2809
+ /** Set terminal scroll region (1-indexed top and bottom rows). */
2810
+ declare function setScrollRegion(stdout: NodeJS.WriteStream, top: number, bottom: number): void;
2811
+ /** Reset scroll region to full terminal. */
2812
+ declare function resetScrollRegion(stdout: NodeJS.WriteStream): void;
2813
+ /** Scroll content up by N lines within the current scroll region. */
2814
+ declare function scrollUp(stdout: NodeJS.WriteStream, lines?: number): void;
2815
+ /** Scroll content down by N lines within the current scroll region. */
2816
+ declare function scrollDown(stdout: NodeJS.WriteStream, lines?: number): void;
2817
+ /** Move cursor to a specific position (1-indexed row and column). */
2818
+ declare function moveCursor(stdout: NodeJS.WriteStream, row: number, col: number): void;
2819
+ interface ScrollRegionConfig {
2820
+ /** Top row of the scrollable area (0-indexed). */
2821
+ top: number;
2822
+ /** Bottom row of the scrollable area (0-indexed). */
2823
+ bottom: number;
2824
+ /** Whether scroll region optimization is enabled. */
2825
+ enabled: boolean;
2826
+ }
2827
+ /**
2828
+ * Detect if the terminal likely supports DECSTBM scroll regions.
2829
+ *
2830
+ * Most modern terminals do (xterm, iTerm2, Kitty, Ghostty, WezTerm, etc.)
2831
+ * but some (e.g., Linux console) may not handle them correctly.
2832
+ *
2833
+ * Pass `emulator` (via `term.emulator` or a test fixture) when in scope.
2834
+ * Without it, this falls back to {@link createTerminalProfile} — the canonical
2835
+ * single-source-of-truth entry point in `@silvery/ansi/profile`. Direct
2836
+ * reads of terminal-signal env vars (TERM / TERM_PROGRAM / …) are banned
2837
+ * outside that module — see `scripts/lint-env-reads.ts`.
2838
+ */
2839
+ declare function supportsScrollRegions(/** Structural emulator — `{ program, TERM }` is all this helper reads. */
2840
+
2841
+ emulator?: {
2842
+ program: string;
2843
+ TERM: string;
2844
+ }): boolean;
2845
+ //#endregion
2846
+ //#region packages/ag-term/src/pane-manager.d.ts
2847
+ /**
2848
+ * Pane Manager - Pure functions for manipulating split layout trees.
2849
+ *
2850
+ * All functions are pure: they return new layout trees, never mutate.
2851
+ * The layout tree is a binary tree where leaves are panes and internal
2852
+ * nodes are splits (horizontal or vertical) with a ratio.
2853
+ */
2854
+ type LayoutNode = {
2855
+ type: "leaf";
2856
+ id: string;
2857
+ } | {
2858
+ type: "split";
2859
+ direction: "horizontal" | "vertical";
2860
+ ratio: number;
2861
+ first: LayoutNode;
2862
+ second: LayoutNode;
2863
+ };
2864
+ /** Create a single-pane layout */
2865
+ declare function createLeaf(id: string): LayoutNode;
2866
+ /** Get all leaf pane IDs in depth-first left-to-right order */
2867
+ declare function getPaneIds(layout: LayoutNode): string[];
2868
+ /** Find the next/previous pane in tab order (depth-first left-to-right) */
2869
+ declare function getTabOrder(layout: LayoutNode): string[];
2870
+ /**
2871
+ * Split a pane into two. Returns new layout tree with the target pane split.
2872
+ * The original pane becomes the first child; the new pane becomes the second.
2873
+ */
2874
+ declare function splitPane(layout: LayoutNode, targetPaneId: string, direction: "horizontal" | "vertical", newPaneId: string, ratio?: number): LayoutNode;
2875
+ /**
2876
+ * Remove a pane from the layout. The sibling takes the full space.
2877
+ * Returns null if the removed pane was the last one.
2878
+ */
2879
+ declare function removePane(layout: LayoutNode, paneId: string): LayoutNode | null;
2880
+ /** Swap two panes' positions in the layout */
2881
+ declare function swapPanes(layout: LayoutNode, paneId1: string, paneId2: string): LayoutNode;
2882
+ /**
2883
+ * Resize a split: adjust the ratio of the nearest ancestor split
2884
+ * that contains the target pane as its first child.
2885
+ * Positive delta = grow (first child gets more), negative = shrink.
2886
+ */
2887
+ declare function resizeSplit(layout: LayoutNode, paneId: string, delta: number): LayoutNode;
2888
+ /**
2889
+ * Find the pane adjacent to the given pane in a direction.
2890
+ *
2891
+ * For left/right: looks for siblings in horizontal splits.
2892
+ * For up/down: looks for siblings in vertical splits.
2893
+ *
2894
+ * Returns null if no adjacent pane exists in that direction.
2895
+ */
2896
+ declare function findAdjacentPane(layout: LayoutNode, paneId: string, direction: "left" | "right" | "up" | "down"): string | null;
2897
+ //#endregion
2898
+ //#region packages/headless/src/find.d.ts
2899
+ interface FindMatch {
2900
+ row: number;
2901
+ startCol: number;
2902
+ endCol: number;
2903
+ }
2904
+ /**
2905
+ * Result from a FindProvider's model-level search.
2906
+ * Represents a match within a virtual list item that may not be on screen.
2907
+ */
2908
+ interface FindResult {
2909
+ /** Virtual list item identifier */
2910
+ itemId: string;
2911
+ /** Character offset within item text */
2912
+ offset: number;
2913
+ /** Match length */
2914
+ length: number;
2915
+ /** Screen row — set after reveal() makes the item visible */
2916
+ row?: number;
2917
+ /** Screen start column — set after reveal() */
2918
+ startCol?: number;
2919
+ }
2920
+ interface FindState {
2921
+ /** Current search query, or null if find is not active */
2922
+ query: string | null;
2923
+ /** All matches in the visible buffer */
2924
+ matches: FindMatch[];
2925
+ /** Index of the currently focused match (-1 if no matches) */
2926
+ currentIndex: number;
2927
+ /** Whether find mode is active */
2928
+ active: boolean;
2929
+ /** Provider-level results (when FindProvider is present) */
2930
+ providerResults: FindResult[];
2931
+ /** Whether provider search is in progress */
2932
+ providerSearching: boolean;
2933
+ }
2934
+ //#endregion
2935
+ //#region packages/ag-term/src/history-buffer.d.ts
2936
+ /**
2937
+ * Ring buffer for frozen scrollback items.
2938
+ *
2939
+ * Each item represents a rendered list entry (card, row, etc.) with its
2940
+ * ANSI snapshot, split rows, and plain-text rows for searching.
2941
+ * When total rows or cached ANSI bytes exceed capacity, the oldest items are
2942
+ * evicted. The byte count tracks the serialized string payload; it is a
2943
+ * deterministic cache budget, not an exact process heap measurement.
2944
+ */
2945
+ interface HistoryItem {
2946
+ key: string | number;
2947
+ ansi: string;
2948
+ rows: string[];
2949
+ plainTextRows: string[];
2950
+ width: number;
2951
+ }
2952
+ interface HistoryBuffer {
2953
+ push(item: HistoryItem): void;
2954
+ readonly totalRows: number;
2955
+ readonly totalBytes: number;
2956
+ readonly itemCount: number;
2957
+ getRows(startRow: number, count: number): string[];
2958
+ getPlainTextRows(startRow: number, count: number): string[];
2959
+ search(query: string): number[];
2960
+ getItemAtRow(row: number): {
2961
+ item: HistoryItem;
2962
+ localRow: number;
2963
+ } | null;
2964
+ clear(): void;
2965
+ readonly capacity: number;
2966
+ readonly capacityBytes: number | null;
2967
+ }
2968
+ //#endregion
2969
+ //#region packages/ag-term/src/viewport-compositor.d.ts
2970
+ interface ComposedViewport {
2971
+ /** History rows to overlay at top of viewport */
2972
+ overlayRows: string[];
2973
+ /** Number of top rows occupied by history */
2974
+ overlayRowCount: number;
2975
+ /** Number of bottom rows for live content */
2976
+ liveRowsVisible: number;
2977
+ /** Whether viewing history */
2978
+ isScrolledUp: boolean;
2979
+ /** Total scrollable height */
2980
+ totalHeight: number;
2981
+ }
2982
+ //#endregion
2983
+ //#region packages/ag-term/src/search-overlay.d.ts
2984
+ /**
2985
+ * Search overlay state machine for virtual inline mode.
2986
+ *
2987
+ * Pure TEA: (action, state) -> [state, effects[]]
2988
+ * Provides incremental search-as-you-type with match navigation.
2989
+ */
2990
+ interface SearchMatch {
2991
+ row: number;
2992
+ startCol: number;
2993
+ endCol: number;
2994
+ }
2995
+ /**
2996
+ * A single contiguous character range within a string that matched a search
2997
+ * query. `start` is inclusive, `end` is exclusive — same convention as
2998
+ * `String.prototype.slice(start, end)`.
2999
+ */
3000
+ interface MatchRange {
3001
+ start: number;
3002
+ end: number;
3003
+ }
3004
+ /**
3005
+ * Find all case-insensitive occurrences of `query` inside `text` and return
3006
+ * their character offsets. Empty query or empty text returns `[]`.
3007
+ *
3008
+ * This is the canonical silvery search-match algorithm. The same logic runs
3009
+ * inside `ListView`'s registered Searchable (to find matches across items)
3010
+ * and is exposed to consumers that render multi-segment items — a LogRow
3011
+ * whose searchable text is a concatenation of field values, but whose visual
3012
+ * rendering splits those fields across separate Text nodes, needs per-segment
3013
+ * ranges to highlight without re-implementing the semantics.
3014
+ *
3015
+ * Ranges are returned in ascending `start` order; overlapping matches are
3016
+ * not produced (`indexOf(..., start = last.start + 1)` advances past each
3017
+ * match start, not past its full length, preserving overlapping runs of
3018
+ * short queries — e.g. `"aa"` in `"aaaa"` yields `[0..2], [1..3], [2..4]`).
3019
+ *
3020
+ * Offsets are CHARACTER offsets into the input string. They are not column
3021
+ * offsets — multi-column wide glyphs are counted as one character here, the
3022
+ * same way the SearchProvider's match-row computation does.
3023
+ */
3024
+ declare function computeMatchRanges(text: string, query: string): MatchRange[];
3025
+ //#endregion
3026
+ //#region packages/ag-term/src/runtime/wrap-measurer-registration.d.ts
3027
+ /**
3028
+ * Wrap-measurer registration for `@silvery/ag-term`.
3029
+ *
3030
+ * `@silvery/ag` exposes a process-level wrap-measurer registry
3031
+ * (`setWrapMeasurer` / `getWrapMeasurer`) so geometry helpers like
3032
+ * `computeSelectionFragments` can ask the active terminal runtime for
3033
+ * grapheme-correct soft-wrap slices. Without registration, the geometry
3034
+ * layer falls back to `\n`-only line splitting — fine for pure-framework
3035
+ * unit tests, wrong for real apps where a 60-char paragraph at width 20
3036
+ * needs to emit 3 fragments.
3037
+ *
3038
+ * **Registration shape (Option B per `hub/silvery/design/overlay-anchor-system.md`
3039
+ * § 8)**: terminal-side `wrapTextWithOffsets` adapts to the registry's
3040
+ * `wrapText(text, maxWidth) → readonly WrapSlice[]` contract. The slice
3041
+ * shape is structurally identical (`text` + `startOffset` + `endOffset`),
3042
+ * so the adapter is a passthrough — no allocation, no reformatting.
3043
+ *
3044
+ * **Lifecycle**: registration happens at module load — see the side-effect
3045
+ * call below. The adapter reads the active scoped measurer (terminal caps,
3046
+ * wide-emoji heuristics, text-sizing) at call time, so caps changes during
3047
+ * a session (e.g., post-DA1 width-detection toggling `maybeWideEmojis`)
3048
+ * are picked up automatically.
3049
+ *
3050
+ * **Test isolation**: tests that need the `\n`-only fallback (pure-`ag`
3051
+ * pathway) call `setWrapMeasurer(null)` in `beforeEach`/`afterEach` and
3052
+ * `restoreDefaultWrapMeasurer()` in `afterAll`. Tests that exercise the
3053
+ * registered path do nothing — the import-time side effect already wired
3054
+ * it up.
3055
+ *
3056
+ * **Multi-Term**: v1 is module-level singleton — see `@silvery/ag/wrap-measurer.ts`
3057
+ * file header for the upgrade path. Single Term-per-process is the
3058
+ * production reality; multi-Term scenarios are research / future work.
3059
+ *
3060
+ * Tracking: bead `km-silvery.softwrap-selection-fragments` (closes Phase
3061
+ * 4b deferred wrap-spanning).
3062
+ */
3063
+ /**
3064
+ * Install the terminal-runtime wrap measurer into `@silvery/ag`'s registry.
3065
+ *
3066
+ * Reads the live registry (`getWrapMeasurer()`) — not a local boolean — to
3067
+ * decide whether to install. This makes the function safe to call after a
3068
+ * `setWrapMeasurer(null)` teardown that bypassed `uninstallTerminalWrapMeasurer`
3069
+ * (e.g. tests that drop the registration through `@silvery/ag`'s own API).
3070
+ *
3071
+ * Idempotent: when our adapter is already the registered measurer, this
3072
+ * is a no-op. When a foreign measurer is registered (rare — only seen if
3073
+ * a test or alternate runtime registered its own), this overwrites it
3074
+ * with our adapter, matching v1's "single Term-per-process" assumption.
3075
+ *
3076
+ * Called automatically at module load (see side-effect below); exported
3077
+ * for tests that want to re-arm after a `setWrapMeasurer(null)` teardown.
3078
+ */
3079
+ declare function installTerminalWrapMeasurer(): void;
3080
+ /**
3081
+ * Reset registration when our adapter is the active measurer. After
3082
+ * calling this, the `@silvery/ag` registry is empty (`getWrapMeasurer()`
3083
+ * returns null) and `computeSelectionFragments` falls back to `\n`-only
3084
+ * splitting. Tests use this to exercise the fallback path; runtime
3085
+ * teardown uses it on Term dispose.
3086
+ *
3087
+ * No-op when a foreign measurer is registered — clearing it would surprise
3088
+ * whoever installed it. Call `setWrapMeasurer(null)` directly if the goal
3089
+ * is to clear unconditionally.
3090
+ */
3091
+ declare function uninstallTerminalWrapMeasurer(): void;
3092
+ /**
3093
+ * Test helper: restore the registry to its post-import-time default
3094
+ * state. Equivalent to `installTerminalWrapMeasurer()` but reads more
3095
+ * naturally in `afterEach` / `afterAll` blocks.
3096
+ */
3097
+ declare function restoreDefaultWrapMeasurer(): void;
3098
+ /**
3099
+ * Read whether the terminal measurer is currently the active registration.
3100
+ * Sources truth from the live registry so a concurrent test that called
3101
+ * `setWrapMeasurer(null)` is observed correctly.
3102
+ */
3103
+ declare function isTerminalWrapMeasurerInstalled(): boolean;
3104
+ //#endregion
3105
+ export { enableFocusReporting as $, hasWideCharacters as $n, RenderStyle as $t, withMeasurer as A, setCursorStyle as An, injectDOMStyles as At, ResolvedNonTTYMode as B, createOsc52Backend as Bn, App as Bt, scrollDown as C, enableKittyKeyboard as Cn, PASTE_START as Ct, calcEdgeBasedScrollOffset as D, resetCursorStyle as Dn, DOMAdapterConfig as Dt, supportsScrollRegions as E, reportDirectory as En, parseBracketedPaste as Et, inspectFrame as F, DragState as Fn, LayoutConstants as Ft, isTerm as G, createMeasurer as Gn, LayoutShift as Gt, resolveNonTTYMode as H, Measurer as Hn, FilterOptions as Ht, inspectTree as I, ClipboardBackend as In, LayoutEngine as It, queryTextAreaSize as J, ensureEmojiPresentation as Jn, ExecuteRenderOptions as Jt, queryCellSize as K, displayWidth as Kn, ReasonClassifier as Kt, isInspectorEnabled as L, ClipboardCapabilities as Ln, LayoutEngineType as Lt, autoEnableInspector as M, setWindowAndIconTitle as Mn, CanvasRenderBuffer as Mt, disableInspector as N, setWindowTitle as Nn, createCanvasAdapter as Nt, MeasuredTerm as O, resetMouseCursorShape as On, DOMRenderBuffer as Ot, enableInspector as P, CopyModeState as Pn, EngineCapabilities as Pt, disableFocusReporting as Q, hasAnsi as Qn, RenderBuffer as Qt, IncrementalRenderMismatchError as R, createCompositeClipboard as Rn, isLayoutEngineInitialized as Rt, resetScrollRegion as S, disableMouse as Sn, PASTE_END as St, setScrollRegion as T, queryKittyKeyboard as Tn, enableBracketedPaste as Tt, TermDef as U, StyledSegment as Un, createAutoLocator as Ut, isTTY as V, parseClipboardResponse as Vn, AutoLocator as Vt, createInputEvents as W, constrainText as Wn, CLSReport as Wt, queryMode as X, graphemeCount as Xn, LayoutSignals as Xt, DecMode as Y, getFirstCodePoint as Yn, PipelineConfig as Yt, queryModes as Z, graphemeWidth as Zn, BorderChars as Zt, resizeSplit as _, BEL as _n, truncateText as _r, KittyDetectResult as _t, MatchRange as a, OutputPhaseDiagnostics as an, isZeroWidthGrapheme as ar, queryTerminalVersion as at, ScrollRegionConfig as b, MouseCursorShape as bn, writeTextToBuffer as br, OSC133 as bt, ComposedViewport as c, CursorAccessors as cn, padText as cr, queryCursorPosition as ct, LayoutNode as d, CursorState as dn, sliceByWidth as dr, isPrivateUseArea as dt, TextMeasureResult as en, hasZeroWidthCharacters as er, parseFocusEvent as et, createLeaf as f, CursorStore as fn, sliceByWidthFromEnd as fr, textSized as ft, removePane as g, ANSI as gn, truncateAnsi as gr, runTermtest as gt, getTabOrder as h, useCursor as hn, stripAnsi as hr, TermtestSection as ht, uninstallTerminalWrapMeasurer as i, OutputCaps as in, isWideGrapheme as ir, querySecondaryDA as it, InspectorOptions as j, setMouseCursorShape as jn, CanvasAdapterConfig as jt, createPipeline as k, resetWindowTitle as kn, createDOMAdapter as kt, HistoryBuffer as l, CursorPosition as ln, parseAnsiText as lr, detectTextSizingSupport as lt, getPaneIds as m, resetCursorState as mn, splitGraphemes as mr, TermtestOptions as mt, isTerminalWrapMeasurerInstalled as n, TextMeasurer as nn, isLikelyEmoji as nr, queryDeviceAttributes as nt, SearchMatch as o, OutputPhaseFn as on, measureText as or, queryTertiaryDA as ot, findAdjacentPane as p, createCursorStore as pn, sliceByWidthRange as pr, TERMTEST_SECTIONS as pt, queryTextAreaPixels as q, displayWidthAnsi as qn, ReflowReason as qt, restoreDefaultWrapMeasurer as r, PipelineContext as rn, isTextSizingEnabled as rr, queryPrimaryDA as rt, computeMatchRanges as s, createOutputPhase as sn, normalizeText as sr, queryCursorFromStdio as st, installTerminalWrapMeasurer as t, TextMeasureStyle as tn, isCJK as tr, DeviceAttributes as tt, FindState as u, CursorProvider as un, runWithMeasurer as ur, getTerminalFingerprint as ut, splitPane as v, CursorShape as vn, wrapText as vr, detectKittyFromStdio as vt, scrollUp as w, enableMouse as wn, disableBracketedPaste as wt, moveCursor as x, disableKittyKeyboard as xn, writeTextTruncated as xr, BracketedPasteResult as xt, swapPanes as y, KittyFlags as yn, writeLinesToBuffer as yr, detectKittySupport as yt, NonTTYOptions as z, createInternalClipboardBackend as zn, setLayoutEngine as zt };
3106
+ //# sourceMappingURL=wrap-measurer-registration-IV2HtcCd.d.mts.map