@deepseek-harness-tui/dsh-tui 0.8.8 → 0.9.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 (215) hide show
  1. package/README.md +27 -8
  2. package/bin/dsh-tui.js +1 -1
  3. package/lib/types/commands.d.ts.map +1 -1
  4. package/lib/types/commands.js +4 -2
  5. package/lib/types/components/ActivityPicker.d.ts +4 -1
  6. package/lib/types/components/ActivityPicker.d.ts.map +1 -1
  7. package/lib/types/components/ActivityPicker.js +2 -2
  8. package/lib/types/components/BtwPanel.d.ts.map +1 -1
  9. package/lib/types/components/BtwPanel.js +1 -1
  10. package/lib/types/components/Chat/SubagentMessage.d.ts +2 -1
  11. package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -1
  12. package/lib/types/components/Chat/SubagentMessage.js +11 -3
  13. package/lib/types/components/CommandSuggestions.d.ts +21 -4
  14. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  15. package/lib/types/components/CommandSuggestions.js +41 -14
  16. package/lib/types/components/EffortSlider.d.ts +4 -1
  17. package/lib/types/components/EffortSlider.d.ts.map +1 -1
  18. package/lib/types/components/EffortSlider.js +4 -2
  19. package/lib/types/components/ExtensionDialog.js +6 -2
  20. package/lib/types/components/FileSuggestions.d.ts +24 -7
  21. package/lib/types/components/FileSuggestions.d.ts.map +1 -1
  22. package/lib/types/components/FileSuggestions.js +39 -12
  23. package/lib/types/components/GoalTodoPanel.d.ts +26 -2
  24. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
  25. package/lib/types/components/GoalTodoPanel.js +86 -17
  26. package/lib/types/components/HelpMenu.d.ts +7 -1
  27. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  28. package/lib/types/components/HelpMenu.js +12 -4
  29. package/lib/types/components/HistorySearchDialog.d.ts +4 -1
  30. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
  31. package/lib/types/components/HistorySearchDialog.js +2 -2
  32. package/lib/types/components/LangPicker.d.ts +14 -0
  33. package/lib/types/components/LangPicker.d.ts.map +1 -0
  34. package/lib/types/components/LangPicker.js +17 -0
  35. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  36. package/lib/types/components/LoadedContextPanel.js +3 -1
  37. package/lib/types/components/Markdown.d.ts.map +1 -1
  38. package/lib/types/components/Markdown.js +12 -3
  39. package/lib/types/components/MessageList.d.ts +43 -2
  40. package/lib/types/components/MessageList.d.ts.map +1 -1
  41. package/lib/types/components/MessageList.js +553 -41
  42. package/lib/types/components/ModelPicker.d.ts +4 -1
  43. package/lib/types/components/ModelPicker.d.ts.map +1 -1
  44. package/lib/types/components/ModelPicker.js +2 -2
  45. package/lib/types/components/PermissionsPicker.d.ts +21 -0
  46. package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
  47. package/lib/types/components/PermissionsPicker.js +27 -0
  48. package/lib/types/components/PlanPicker.d.ts +15 -0
  49. package/lib/types/components/PlanPicker.d.ts.map +1 -0
  50. package/lib/types/components/PlanPicker.js +18 -0
  51. package/lib/types/components/PresetPicker.d.ts +4 -1
  52. package/lib/types/components/PresetPicker.d.ts.map +1 -1
  53. package/lib/types/components/PresetPicker.js +2 -2
  54. package/lib/types/components/PromptInput.d.ts +4 -3
  55. package/lib/types/components/PromptInput.d.ts.map +1 -1
  56. package/lib/types/components/PromptInput.js +248 -29
  57. package/lib/types/components/RewindPicker.d.ts +12 -1
  58. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  59. package/lib/types/components/RewindPicker.js +6 -4
  60. package/lib/types/components/ScrollbarGutter.d.ts +28 -0
  61. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
  62. package/lib/types/components/ScrollbarGutter.js +68 -0
  63. package/lib/types/components/Select.d.ts +8 -1
  64. package/lib/types/components/Select.d.ts.map +1 -1
  65. package/lib/types/components/Select.js +4 -2
  66. package/lib/types/components/SkillsPicker.d.ts +4 -1
  67. package/lib/types/components/SkillsPicker.d.ts.map +1 -1
  68. package/lib/types/components/SkillsPicker.js +2 -2
  69. package/lib/types/components/SubagentCard.d.ts +2 -1
  70. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  71. package/lib/types/components/SubagentCard.js +6 -1
  72. package/lib/types/components/SubagentDashboard.d.ts +4 -0
  73. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  74. package/lib/types/components/SubagentDashboard.js +9 -1
  75. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  76. package/lib/types/components/SubagentDetailScene.js +5 -4
  77. package/lib/types/components/SuggestionCard.d.ts +63 -0
  78. package/lib/types/components/SuggestionCard.d.ts.map +1 -0
  79. package/lib/types/components/SuggestionCard.js +77 -0
  80. package/lib/types/components/ThemePicker.d.ts +4 -1
  81. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  82. package/lib/types/components/ThemePicker.js +2 -2
  83. package/lib/types/components/ThinkingToggle.d.ts +4 -1
  84. package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
  85. package/lib/types/components/ThinkingToggle.js +2 -2
  86. package/lib/types/components/TimelineRail.d.ts +53 -0
  87. package/lib/types/components/TimelineRail.d.ts.map +1 -0
  88. package/lib/types/components/TimelineRail.js +190 -0
  89. package/lib/types/components/WorkspaceFlowPicker.d.ts +6 -1
  90. package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -1
  91. package/lib/types/components/WorkspaceFlowPicker.js +4 -2
  92. package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
  93. package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
  94. package/lib/types/components/WorkspaceMenuPicker.js +19 -0
  95. package/lib/types/components/WorkspacePicker.d.ts +4 -1
  96. package/lib/types/components/WorkspacePicker.d.ts.map +1 -1
  97. package/lib/types/components/WorkspacePicker.js +2 -2
  98. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
  99. package/lib/types/components/approvals/ApprovalPanel.js +5 -1
  100. package/lib/types/components/design-system/ListItem.d.ts +8 -1
  101. package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
  102. package/lib/types/components/design-system/ListItem.js +8 -3
  103. package/lib/types/components/messages/AssistantTextMessage.d.ts +5 -2
  104. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
  105. package/lib/types/components/messages/AssistantTextMessage.js +6 -2
  106. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  107. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  108. package/lib/types/components/messages/AssistantThinkingMessage.js +10 -4
  109. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +8 -1
  110. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  111. package/lib/types/components/messages/AssistantToolUseMessage.js +4 -2
  112. package/lib/types/components/messages/UserPromptMessage.d.ts +2 -1
  113. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  114. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  115. package/lib/types/components/questions/AskUserQuestionPanel.js +34 -2
  116. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  117. package/lib/types/components/questions/PlanReviewPanel.js +13 -2
  118. package/lib/types/components/sessions/SessionListRow.d.ts +4 -1
  119. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
  120. package/lib/types/components/sessions/SessionListRow.js +4 -2
  121. package/lib/types/components/trajectory/HotspotView.d.ts +7 -1
  122. package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -1
  123. package/lib/types/components/trajectory/HotspotView.js +8 -2
  124. package/lib/types/components/trajectory/Ledger.d.ts +9 -1
  125. package/lib/types/components/trajectory/Ledger.d.ts.map +1 -1
  126. package/lib/types/components/trajectory/Ledger.js +23 -5
  127. package/lib/types/components/trajectory/WaveBand.d.ts +10 -1
  128. package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -1
  129. package/lib/types/components/trajectory/WaveBand.js +7 -2
  130. package/lib/types/dsh-adapter/channel.d.ts +16 -5
  131. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/channel.js +332 -29
  133. package/lib/types/dsh-adapter/index.d.ts +10 -2
  134. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  135. package/lib/types/dsh-adapter/index.js +4 -1
  136. package/lib/types/dsh-adapter/plugin.d.ts +0 -9
  137. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  138. package/lib/types/dsh-adapter/plugin.js +136 -6
  139. package/lib/types/i18n.d.ts +176 -15
  140. package/lib/types/i18n.d.ts.map +1 -1
  141. package/lib/types/i18n.js +51 -8
  142. package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -1
  143. package/lib/types/ink/components/AlternateScreen.js +13 -1
  144. package/lib/types/ink/components/App.d.ts +12 -1
  145. package/lib/types/ink/components/App.d.ts.map +1 -1
  146. package/lib/types/ink/components/App.js +101 -4
  147. package/lib/types/ink/components/ClockContext.d.ts.map +1 -1
  148. package/lib/types/ink/components/ClockContext.js +2 -0
  149. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  150. package/lib/types/ink/components/ScrollBox.js +170 -91
  151. package/lib/types/ink/constants.d.ts +9 -0
  152. package/lib/types/ink/constants.d.ts.map +1 -1
  153. package/lib/types/ink/constants.js +9 -0
  154. package/lib/types/ink/events/click-event.d.ts +7 -16
  155. package/lib/types/ink/events/click-event.d.ts.map +1 -1
  156. package/lib/types/ink/events/click-event.js +16 -19
  157. package/lib/types/ink/events/event-handlers.d.ts +11 -1
  158. package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
  159. package/lib/types/ink/events/event-handlers.js +2 -0
  160. package/lib/types/ink/events/input-event.d.ts +9 -0
  161. package/lib/types/ink/events/input-event.d.ts.map +1 -1
  162. package/lib/types/ink/events/input-event.js +4 -0
  163. package/lib/types/ink/events/pointer-event.d.ts +61 -0
  164. package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
  165. package/lib/types/ink/events/pointer-event.js +61 -0
  166. package/lib/types/ink/events/wheel-event.d.ts +17 -0
  167. package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
  168. package/lib/types/ink/events/wheel-event.js +20 -0
  169. package/lib/types/ink/geometry-trace.d.ts +51 -0
  170. package/lib/types/ink/geometry-trace.d.ts.map +1 -0
  171. package/lib/types/ink/geometry-trace.js +83 -0
  172. package/lib/types/ink/hit-test.d.ts +56 -1
  173. package/lib/types/ink/hit-test.d.ts.map +1 -1
  174. package/lib/types/ink/hit-test.js +146 -8
  175. package/lib/types/ink/ink.d.ts +58 -1
  176. package/lib/types/ink/ink.d.ts.map +1 -1
  177. package/lib/types/ink/ink.js +230 -29
  178. package/lib/types/ink/node-cache.d.ts +5 -0
  179. package/lib/types/ink/node-cache.d.ts.map +1 -1
  180. package/lib/types/ink/parse-keypress.d.ts +8 -0
  181. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  182. package/lib/types/ink/parse-keypress.js +101 -12
  183. package/lib/types/ink/render-node-to-output.d.ts +10 -0
  184. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  185. package/lib/types/ink/render-node-to-output.js +111 -18
  186. package/lib/types/ink/timeline-rail.d.ts +138 -0
  187. package/lib/types/ink/timeline-rail.d.ts.map +1 -0
  188. package/lib/types/ink/timeline-rail.js +179 -0
  189. package/lib/types/ink/wrap-text.d.ts.map +1 -1
  190. package/lib/types/ink/wrap-text.js +47 -5
  191. package/lib/types/screens/Chat.d.ts.map +1 -1
  192. package/lib/types/screens/Chat.js +819 -337
  193. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  194. package/lib/types/screens/SessionBrowser.js +56 -29
  195. package/lib/types/screens/Settings.d.ts.map +1 -1
  196. package/lib/types/screens/Settings.js +64 -22
  197. package/lib/types/screens/StatusLine.d.ts +2 -1
  198. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  199. package/lib/types/screens/StatusLine.js +17 -1
  200. package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
  201. package/lib/types/screens/TrajectoryScene.js +81 -14
  202. package/lib/types/screens/chatOverlay.d.ts +221 -0
  203. package/lib/types/screens/chatOverlay.d.ts.map +1 -0
  204. package/lib/types/screens/chatOverlay.js +114 -0
  205. package/lib/types/tips.d.ts.map +1 -1
  206. package/lib/types/tips.js +42 -6
  207. package/lib/types/tuiDisplayPrefs.d.ts +15 -0
  208. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  209. package/lib/types/tuiDisplayPrefs.js +9 -0
  210. package/lib/types/utils/debug.d.ts +10 -0
  211. package/lib/types/utils/debug.d.ts.map +1 -1
  212. package/lib/types/utils/debug.js +24 -0
  213. package/lib/types/utils/paths.d.ts.map +1 -1
  214. package/lib/types/utils/paths.js +1 -0
  215. package/package.json +4 -2
@@ -0,0 +1,61 @@
1
+ import { nodeCache } from '../node-cache.js';
2
+ import { TerminalEvent } from './terminal-event.js';
3
+ /**
4
+ * Base class for pointer-derived terminal events (click, wheel, hover).
5
+ *
6
+ * Carries the raw SGR/X10 button byte so handlers can read modifier flags
7
+ * (`shift`/`alt`/`ctrl`) without re-parsing the escape sequence, plus
8
+ * per-handler local coordinates: `_prepareForTarget` recomputes
9
+ * `localCol`/`localRow` from the nodeCache rect before each handler fires,
10
+ * so an onClick on a container sees coordinates relative to that container,
11
+ * not to the child the pointer actually landed on.
12
+ *
13
+ * `meta` is deliberately always false: xterm.js drops metaKey before SGR
14
+ * encoding (the SGR bit we call "meta" is wired to alt), so no pointer
15
+ * protocol can distinguish it reliably.
16
+ */
17
+ export class PointerEvent extends TerminalEvent {
18
+ /** 0-indexed screen column of the pointer. */
19
+ col;
20
+ /** 0-indexed screen row of the pointer. */
21
+ row;
22
+ /** Raw protocol button byte (SGR encoding). */
23
+ button;
24
+ /** Which pointer action produced this event. */
25
+ action;
26
+ /** Shift held (SGR button bit 0x04). */
27
+ shift;
28
+ /** Alt/Option held (SGR button bit 0x08). */
29
+ alt;
30
+ /** Ctrl held (SGR button bit 0x10). */
31
+ ctrl;
32
+ /** Always false — see class doc. */
33
+ meta = false;
34
+ /** Column relative to the current handler's node (set during dispatch). */
35
+ localCol = 0;
36
+ /** Row relative to the current handler's node (set during dispatch). */
37
+ localRow = 0;
38
+ constructor(type, col, row, init) {
39
+ super(type, {
40
+ bubbles: init?.bubbles ?? true,
41
+ cancelable: init?.cancelable ?? true,
42
+ });
43
+ this.col = col;
44
+ this.row = row;
45
+ this.button = init?.button ?? 0;
46
+ this.action = init?.action ?? 'move';
47
+ this.shift = (this.button & 0x04) !== 0;
48
+ this.alt = (this.button & 0x08) !== 0;
49
+ this.ctrl = (this.button & 0x10) !== 0;
50
+ }
51
+ /**
52
+ * Refresh localCol/localRow for the node whose handler is about to run.
53
+ * Nodes without a cached rect (not rendered this frame) get 0,0 — handlers
54
+ * should prefer absolute col/row when that distinction matters.
55
+ */
56
+ _prepareForTarget(target) {
57
+ const rect = nodeCache.get(target);
58
+ this.localCol = rect ? this.col - rect.x : 0;
59
+ this.localRow = rect ? this.row - rect.y : 0;
60
+ }
61
+ }
@@ -0,0 +1,17 @@
1
+ import { PointerEvent, type PointerEventInit } from './pointer-event.js';
2
+ /**
3
+ * Mouse wheel event dispatched to the ScrollBox under the pointer.
4
+ *
5
+ * `deltaY`/`deltaX` are in terminal rows/columns per wheel notch (positive =
6
+ * content moves up / right, i.e. scroll down / scroll right), matching
7
+ * ScrollBox.scrollBy's sign convention. Coordinates identify where the wheel
8
+ * event occurred so routing can hit-test the deepest scroll container.
9
+ */
10
+ export declare class WheelEvent extends PointerEvent {
11
+ /** Rows to scroll (positive = scroll down). */
12
+ readonly deltaY: number;
13
+ /** Columns to scroll (positive = scroll right; currently informational). */
14
+ readonly deltaX: number;
15
+ constructor(col: number, row: number, deltaY: number, deltaX?: number, init?: PointerEventInit);
16
+ }
17
+ //# sourceMappingURL=wheel-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wheel-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/wheel-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAExE;;;;;;;GAOG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;gBAGrB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,SAAI,EACV,IAAI,CAAC,EAAE,gBAAgB;CAM1B"}
@@ -0,0 +1,20 @@
1
+ import { PointerEvent } from './pointer-event.js';
2
+ /**
3
+ * Mouse wheel event dispatched to the ScrollBox under the pointer.
4
+ *
5
+ * `deltaY`/`deltaX` are in terminal rows/columns per wheel notch (positive =
6
+ * content moves up / right, i.e. scroll down / scroll right), matching
7
+ * ScrollBox.scrollBy's sign convention. Coordinates identify where the wheel
8
+ * event occurred so routing can hit-test the deepest scroll container.
9
+ */
10
+ export class WheelEvent extends PointerEvent {
11
+ /** Rows to scroll (positive = scroll down). */
12
+ deltaY;
13
+ /** Columns to scroll (positive = scroll right; currently informational). */
14
+ deltaX;
15
+ constructor(col, row, deltaY, deltaX = 0, init) {
16
+ super('wheel', col, row, { ...init, action: 'move' });
17
+ this.deltaY = deltaY;
18
+ this.deltaX = deltaX;
19
+ }
20
+ }
@@ -0,0 +1,51 @@
1
+ export type FrameCause = 'react-commit' | 'animation' | 'scroll' | 'scroll-drain' | 'measure' | 'resize' | 'reanchor' | 'immediate';
2
+ export declare const GEOMETRY_TRACE_ENABLED: boolean;
3
+ export type ScrollGeometryNote = {
4
+ sticky: boolean;
5
+ shrunk: boolean;
6
+ grew: boolean;
7
+ atBottom: boolean;
8
+ /** scrollTop captured before at-bottom follow (the user's logical view). */
9
+ scrollTopBeforeFollow: number;
10
+ /** scrollTop after pendingScrollDelta drain, before clamps. */
11
+ cur: number;
12
+ /** scrollTop written back to the DOM node (post follow/drain, pre virtual clamp). */
13
+ scrollTop: number;
14
+ /** What actually gets painted this frame (post cMin/cMax virtual clamp). */
15
+ renderScrollTop: number;
16
+ scrollHeight: number;
17
+ prevScrollHeight: number;
18
+ innerHeight: number;
19
+ maxScroll: number;
20
+ prevMaxScroll: number;
21
+ clampMin: number | null;
22
+ clampMax: number | null;
23
+ };
24
+ export type ListGeometryNote = {
25
+ start: number;
26
+ end: number;
27
+ topPad: number;
28
+ bottomPad: number;
29
+ /** Estimated total content height from cached row heights. */
30
+ total: number;
31
+ base: number;
32
+ sticky: boolean;
33
+ pending: number;
34
+ viewport: number;
35
+ termRows: number;
36
+ columns: number;
37
+ rowCount: number;
38
+ };
39
+ /** Tag the origin of the next painted frame. First note in the window wins. */
40
+ export declare function noteFrameCause(cause: FrameCause): void;
41
+ /** Renderer-side note, one per ScrollBox encountered during the paint. */
42
+ export declare function noteScrollGeometry(note: ScrollGeometryNote): void;
43
+ /** React-side note from MessageList's virtualization pass (latest wins). */
44
+ export declare function noteListGeometry(note: ListGeometryNote): void;
45
+ /** Scalar forensics (PromptInput content rows, …). Latest wins. */
46
+ export declare function noteAuxNumber(key: string, value: number): void;
47
+ /** Paint begins: just tag the frame id — inter-frame notes belong to it. */
48
+ export declare function beginGeometryFrame(frame: number): void;
49
+ /** Paint ends: flush one JSON line and reset the inter-frame window. */
50
+ export declare function endGeometryFrame(durationMs: number): void;
51
+ //# sourceMappingURL=geometry-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry-trace.d.ts","sourceRoot":"","sources":["../../../src/ink/geometry-trace.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,WAAW,GACX,QAAQ,GACR,cAAc,GACd,SAAS,GACT,QAAQ,GACR,UAAU,GACV,WAAW,CAAA;AAEf,eAAO,MAAM,sBAAsB,SACQ,CAAA;AAI3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,qBAAqB,EAAE,MAAM,CAAA;IAC7B,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX,qFAAqF;IACrF,SAAS,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAkBD,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAGtD;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAGjE;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAG7D;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAG9D;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGtD;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAmBzD"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Geometry forensics — per-frame scroll-geometry trace (issues #421/#433).
3
+ *
4
+ * `DSH_TUI_GEOMETRY_TRACE=<file>` appends one JSON line per painted frame:
5
+ * the frame's trigger cause, every ScrollBox's resolved geometry (scrollTop
6
+ * before/after follow + drain + virtual clamp, scrollHeight/maxScroll
7
+ * prev/cur, sticky/shrunk/grew flags, clamp bounds), the MessageList
8
+ * virtualization window, and aux counters (e.g. PromptInput content rows).
9
+ *
10
+ * Zero overhead when the env is unset: every entry point returns on a
11
+ * module-const boolean, so the disabled path is a single predictable branch.
12
+ *
13
+ * Ordering contract: causes and React-side notes (list geometry, aux) land
14
+ * BETWEEN frames — at event/commit time, before the throttled paint. The
15
+ * renderer adds scroll geometry during the paint; endGeometryFrame flushes
16
+ * and resets. First-noted cause wins (the origin of the frame chain); no
17
+ * note at paint time means a plain reconciler commit.
18
+ */
19
+ import { appendFileSync } from 'node:fs';
20
+ export const GEOMETRY_TRACE_ENABLED = process.env.DSH_TUI_GEOMETRY_TRACE !== undefined &&
21
+ process.env.DSH_TUI_GEOMETRY_TRACE !== '';
22
+ const TRACE_PATH = process.env.DSH_TUI_GEOMETRY_TRACE ?? '';
23
+ let state = {
24
+ frame: -1,
25
+ cause: null,
26
+ scroll: [],
27
+ list: null,
28
+ aux: {}
29
+ };
30
+ /** Tag the origin of the next painted frame. First note in the window wins. */
31
+ export function noteFrameCause(cause) {
32
+ if (!GEOMETRY_TRACE_ENABLED)
33
+ return;
34
+ if (state.cause === null)
35
+ state.cause = cause;
36
+ }
37
+ /** Renderer-side note, one per ScrollBox encountered during the paint. */
38
+ export function noteScrollGeometry(note) {
39
+ if (!GEOMETRY_TRACE_ENABLED)
40
+ return;
41
+ state.scroll.push(note);
42
+ }
43
+ /** React-side note from MessageList's virtualization pass (latest wins). */
44
+ export function noteListGeometry(note) {
45
+ if (!GEOMETRY_TRACE_ENABLED)
46
+ return;
47
+ state.list = note;
48
+ }
49
+ /** Scalar forensics (PromptInput content rows, …). Latest wins. */
50
+ export function noteAuxNumber(key, value) {
51
+ if (!GEOMETRY_TRACE_ENABLED)
52
+ return;
53
+ state.aux[key] = value;
54
+ }
55
+ /** Paint begins: just tag the frame id — inter-frame notes belong to it. */
56
+ export function beginGeometryFrame(frame) {
57
+ if (!GEOMETRY_TRACE_ENABLED)
58
+ return;
59
+ state.frame = frame;
60
+ }
61
+ /** Paint ends: flush one JSON line and reset the inter-frame window. */
62
+ export function endGeometryFrame(durationMs) {
63
+ if (!GEOMETRY_TRACE_ENABLED)
64
+ return;
65
+ if (state.frame >= 0) {
66
+ const line = JSON.stringify({
67
+ t: new Date().toISOString(),
68
+ frame: state.frame,
69
+ cause: state.cause ?? 'react-commit',
70
+ ms: Math.round(durationMs * 10) / 10,
71
+ scroll: state.scroll,
72
+ list: state.list,
73
+ aux: state.aux
74
+ });
75
+ try {
76
+ appendFileSync(TRACE_PATH, line + '\n');
77
+ }
78
+ catch {
79
+ // Unwritable path etc. — forensics must never break rendering.
80
+ }
81
+ }
82
+ state = { frame: -1, cause: null, scroll: [], list: null, aux: {} };
83
+ }
@@ -16,18 +16,69 @@ import type { DOMElement } from './dom.js';
16
16
  * @returns the deepest element whose rect contains (col, row), or null.
17
17
  */
18
18
  export declare function hitTest(node: DOMElement, col: number, row: number): DOMElement | null;
19
+ /**
20
+ * hitTest, but overlay-aware: absolute-positioned nodes can paint OUTSIDE
21
+ * every ancestor's rect (OverlayAbove's `bottom:'100%'` pickers float over
22
+ * the transcript), so the plain containment recursion never reaches them —
23
+ * a click on the picker lands in the ScrollBox's rows instead. Check the
24
+ * frame's absolute hit list FIRST, in reverse paint order (later = visually
25
+ * on top), then fall back to the in-flow tree.
26
+ * @param root - the tree root for the in-flow fallback.
27
+ * @param col - the screen column to test.
28
+ * @param row - the screen row to test.
29
+ * @returns the deepest element at (col, row), or null.
30
+ */
31
+ export declare function hitTestWithOverlays(root: DOMElement, col: number, row: number): DOMElement | null;
19
32
  /**
20
33
  * Hit-test the root at (col, row) and bubble a ClickEvent from the deepest
21
34
  * containing node up through parentNode. Only nodes with an onClick handler
22
35
  * fire. Stops when a handler calls stopImmediatePropagation(). Returns
23
36
  * true if at least one onClick handler fired.
37
+ *
38
+ * Each handler call is isolated: a throwing handler is logged and the
39
+ * bubbling continues, so one broken onClick cannot swallow the click from
40
+ * its ancestors or the rest of the input batch.
41
+ *
24
42
  * @param root - the tree root to hit-test.
25
43
  * @param col - the screen column of the click.
26
44
  * @param row - the screen row of the click.
27
45
  * @param cellIsBlank - whether the clicked cell is blank, reported on the event.
46
+ * @param button - raw SGR release byte (carries shift/alt/ctrl modifier bits).
28
47
  * @returns true when at least one onClick handler fired.
29
48
  */
30
- export declare function dispatchClick(root: DOMElement, col: number, row: number, cellIsBlank?: boolean): boolean;
49
+ export declare function dispatchClick(root: DOMElement, col: number, row: number, cellIsBlank?: boolean, button?: number): boolean;
50
+ /**
51
+ * Fire onMouseLeave on every tracked hover node, then empty the set.
52
+ *
53
+ * The pointer-state resets (alt-screen swap, terminal resize) drop the hover
54
+ * set because the geometry it was computed against is gone. But the React
55
+ * components behind those nodes still hold their `hovered=true` state: a bare
56
+ * `set.clear()` never tells them the pointer "left", so every row crossed
57
+ * before the reset keeps its highlight forever — the next motion event only
58
+ * fires enter on the new row (the old nodes are no longer in the set, so no
59
+ * diff ever produces their leave). Firing leave first is what makes the
60
+ * reset invisible to the rows.
61
+ *
62
+ * @param hovered - the tracked hover set; emptied in place.
63
+ * @param col - pointer column for the synthetic leave events (-1 = unknown).
64
+ * @param row - pointer row for the synthetic leave events.
65
+ */
66
+ export declare function clearHovered(hovered: Set<DOMElement>, col?: number, row?: number): void;
67
+ /**
68
+ * Route a wheel event to the ScrollBox (or any onWheel handler) under the
69
+ * pointer. Dispatches through the shared Dispatcher at continuous priority
70
+ * so the event bubbles from the deepest hit node and React schedules any
71
+ * state updates at the right lane.
72
+ *
73
+ * @param root - the tree root to hit-test.
74
+ * @param col - the screen column of the wheel event.
75
+ * @param row - the screen row of the wheel event.
76
+ * @param deltaY - rows to scroll (positive = scroll down).
77
+ * @param deltaX - columns to scroll (positive = right; informational).
78
+ * @param button - raw SGR byte (carries modifier bits).
79
+ * @returns true when an onWheel handler existed under the pointer.
80
+ */
81
+ export declare function dispatchWheel(root: DOMElement, col: number, row: number, deltaY: number, deltaX?: number, button?: number): boolean;
31
82
  /**
32
83
  * Fire onMouseEnter/onMouseLeave as the pointer moves. Like DOM
33
84
  * mouseenter/mouseleave: does NOT bubble — moving between children does
@@ -35,6 +86,10 @@ export declare function dispatchClick(root: DOMElement, col: number, row: number
35
86
  * ancestor with a hover handler; diffs against the previous hovered set;
36
87
  * fires leave on the nodes exited, enter on the nodes entered.
37
88
  *
89
+ * Handlers receive a PointerEvent ('hover') with the pointer position;
90
+ * existing `() => void` handlers simply ignore the argument. Each call is
91
+ * isolated so one throwing handler cannot break the rest of the diff.
92
+ *
38
93
  * Mutates `hovered` in place so the caller (App instance) can hold it
39
94
  * across calls. Clears the set when the hit is null (cursor moved into a
40
95
  * non-rendered gap or off the root rect).
@@ -1 +1 @@
1
- {"version":3,"file":"hit-test.d.ts","sourceRoot":"","sources":["../../../src/ink/hit-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAK1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,UAAU,GAAG,IAAI,CAmBnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,WAAW,UAAQ,GAClB,OAAO,CAmCT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,GACvB,IAAI,CAuBN"}
1
+ {"version":3,"file":"hit-test.d.ts","sourceRoot":"","sources":["../../../src/ink/hit-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAU1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,UAAU,GAAG,IAAI,CAmBnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,UAAU,GAAG,IAAI,CAkBnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,WAAW,UAAQ,EACnB,MAAM,SAAI,GACT,OAAO,CA2CT;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,EACxB,GAAG,SAAK,EACR,GAAG,SAAK,GACP,IAAI,CAiBN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,SAAI,EACV,MAAM,SAAI,GACT,OAAO,CAcT;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,GACvB,IAAI,CAwCN"}
@@ -1,5 +1,10 @@
1
1
  import { ClickEvent } from './events/click-event.js';
2
+ import { PointerEvent } from './events/pointer-event.js';
3
+ import { WheelEvent } from './events/wheel-event.js';
4
+ import { logError } from '../utils/log.js';
2
5
  import { nodeCache } from './node-cache.js';
6
+ import { getAbsoluteHitList } from './render-node-to-output.js';
7
+ import { dispatcher } from './reconciler.js';
3
8
  /**
4
9
  * Find the deepest DOM element whose rendered rect contains (col, row).
5
10
  *
@@ -37,19 +42,55 @@ export function hitTest(node, col, row) {
37
42
  }
38
43
  return node;
39
44
  }
45
+ /**
46
+ * hitTest, but overlay-aware: absolute-positioned nodes can paint OUTSIDE
47
+ * every ancestor's rect (OverlayAbove's `bottom:'100%'` pickers float over
48
+ * the transcript), so the plain containment recursion never reaches them —
49
+ * a click on the picker lands in the ScrollBox's rows instead. Check the
50
+ * frame's absolute hit list FIRST, in reverse paint order (later = visually
51
+ * on top), then fall back to the in-flow tree.
52
+ * @param root - the tree root for the in-flow fallback.
53
+ * @param col - the screen column to test.
54
+ * @param row - the screen row to test.
55
+ * @returns the deepest element at (col, row), or null.
56
+ */
57
+ export function hitTestWithOverlays(root, col, row) {
58
+ const overlays = getAbsoluteHitList();
59
+ for (let i = overlays.length - 1; i >= 0; i--) {
60
+ const { node, rect } = overlays[i];
61
+ if (col >= rect.x &&
62
+ col < rect.x + rect.width &&
63
+ row >= rect.y &&
64
+ row < rect.y + rect.height) {
65
+ // hitTest re-checks containment via nodeCache and descends normally;
66
+ // nested absolutes deeper inside are themselves in the list and were
67
+ // already offered (later paint order) above.
68
+ const hit = hitTest(node, col, row);
69
+ if (hit)
70
+ return hit;
71
+ }
72
+ }
73
+ return hitTest(root, col, row);
74
+ }
40
75
  /**
41
76
  * Hit-test the root at (col, row) and bubble a ClickEvent from the deepest
42
77
  * containing node up through parentNode. Only nodes with an onClick handler
43
78
  * fire. Stops when a handler calls stopImmediatePropagation(). Returns
44
79
  * true if at least one onClick handler fired.
80
+ *
81
+ * Each handler call is isolated: a throwing handler is logged and the
82
+ * bubbling continues, so one broken onClick cannot swallow the click from
83
+ * its ancestors or the rest of the input batch.
84
+ *
45
85
  * @param root - the tree root to hit-test.
46
86
  * @param col - the screen column of the click.
47
87
  * @param row - the screen row of the click.
48
88
  * @param cellIsBlank - whether the clicked cell is blank, reported on the event.
89
+ * @param button - raw SGR release byte (carries shift/alt/ctrl modifier bits).
49
90
  * @returns true when at least one onClick handler fired.
50
91
  */
51
- export function dispatchClick(root, col, row, cellIsBlank = false) {
52
- let target = hitTest(root, col, row) ?? undefined;
92
+ export function dispatchClick(root, col, row, cellIsBlank = false, button = 0) {
93
+ let target = hitTestWithOverlays(root, col, row) ?? undefined;
53
94
  if (!target)
54
95
  return false;
55
96
  // Click-to-focus: find the closest focusable ancestor and focus it.
@@ -64,7 +105,7 @@ export function dispatchClick(root, col, row, cellIsBlank = false) {
64
105
  focusTarget = focusTarget.parentNode;
65
106
  }
66
107
  }
67
- const event = new ClickEvent(col, row, cellIsBlank);
108
+ const event = new ClickEvent(col, row, cellIsBlank, { button });
68
109
  let handled = false;
69
110
  while (target) {
70
111
  const handler = target._eventHandlers?.onClick;
@@ -75,7 +116,16 @@ export function dispatchClick(root, col, row, cellIsBlank = false) {
75
116
  event.localCol = col - rect.x;
76
117
  event.localRow = row - rect.y;
77
118
  }
78
- handler(event);
119
+ else {
120
+ event.localCol = 0;
121
+ event.localRow = 0;
122
+ }
123
+ try {
124
+ handler(event);
125
+ }
126
+ catch (error) {
127
+ logError(error);
128
+ }
79
129
  if (event.didStopImmediatePropagation())
80
130
  return true;
81
131
  }
@@ -83,6 +133,73 @@ export function dispatchClick(root, col, row, cellIsBlank = false) {
83
133
  }
84
134
  return handled;
85
135
  }
136
+ /**
137
+ * Fire onMouseLeave on every tracked hover node, then empty the set.
138
+ *
139
+ * The pointer-state resets (alt-screen swap, terminal resize) drop the hover
140
+ * set because the geometry it was computed against is gone. But the React
141
+ * components behind those nodes still hold their `hovered=true` state: a bare
142
+ * `set.clear()` never tells them the pointer "left", so every row crossed
143
+ * before the reset keeps its highlight forever — the next motion event only
144
+ * fires enter on the new row (the old nodes are no longer in the set, so no
145
+ * diff ever produces their leave). Firing leave first is what makes the
146
+ * reset invisible to the rows.
147
+ *
148
+ * @param hovered - the tracked hover set; emptied in place.
149
+ * @param col - pointer column for the synthetic leave events (-1 = unknown).
150
+ * @param row - pointer row for the synthetic leave events.
151
+ */
152
+ export function clearHovered(hovered, col = -1, row = -1) {
153
+ for (const node of hovered) {
154
+ hovered.delete(node);
155
+ // Detached nodes (screen already swapped out from under us) can no
156
+ // longer re-render — skip them; their component state dies with the
157
+ // subtree anyway.
158
+ if (!node.parentNode)
159
+ continue;
160
+ const handler = node._eventHandlers
161
+ ?.onMouseLeave;
162
+ if (handler) {
163
+ try {
164
+ handler(new PointerEvent('hover', col, row, { action: 'move' }));
165
+ }
166
+ catch (error) {
167
+ logError(error);
168
+ }
169
+ }
170
+ }
171
+ }
172
+ /**
173
+ * Route a wheel event to the ScrollBox (or any onWheel handler) under the
174
+ * pointer. Dispatches through the shared Dispatcher at continuous priority
175
+ * so the event bubbles from the deepest hit node and React schedules any
176
+ * state updates at the right lane.
177
+ *
178
+ * @param root - the tree root to hit-test.
179
+ * @param col - the screen column of the wheel event.
180
+ * @param row - the screen row of the wheel event.
181
+ * @param deltaY - rows to scroll (positive = scroll down).
182
+ * @param deltaX - columns to scroll (positive = right; informational).
183
+ * @param button - raw SGR byte (carries modifier bits).
184
+ * @returns true when an onWheel handler existed under the pointer.
185
+ */
186
+ export function dispatchWheel(root, col, row, deltaY, deltaX = 0, button = 0) {
187
+ const target = hitTestWithOverlays(root, col, row);
188
+ if (!target)
189
+ return false;
190
+ // Does any ancestor (target inclusive) carry an onWheel handler?
191
+ let node = target;
192
+ let hasHandler = false;
193
+ while (node && !hasHandler) {
194
+ hasHandler = Boolean(node._eventHandlers?.onWheel);
195
+ node = node.parentNode;
196
+ }
197
+ if (!hasHandler)
198
+ return false;
199
+ const event = new WheelEvent(col, row, deltaY, deltaX, { button });
200
+ dispatcher.dispatchContinuous(target, event);
201
+ return true;
202
+ }
86
203
  /**
87
204
  * Fire onMouseEnter/onMouseLeave as the pointer moves. Like DOM
88
205
  * mouseenter/mouseleave: does NOT bubble — moving between children does
@@ -90,6 +207,10 @@ export function dispatchClick(root, col, row, cellIsBlank = false) {
90
207
  * ancestor with a hover handler; diffs against the previous hovered set;
91
208
  * fires leave on the nodes exited, enter on the nodes entered.
92
209
  *
210
+ * Handlers receive a PointerEvent ('hover') with the pointer position;
211
+ * existing `() => void` handlers simply ignore the argument. Each call is
212
+ * isolated so one throwing handler cannot break the rest of the diff.
213
+ *
93
214
  * Mutates `hovered` in place so the caller (App instance) can hold it
94
215
  * across calls. Clears the set when the hit is null (cursor moved into a
95
216
  * non-rendered gap or off the root rect).
@@ -100,7 +221,7 @@ export function dispatchClick(root, col, row, cellIsBlank = false) {
100
221
  */
101
222
  export function dispatchHover(root, col, row, hovered) {
102
223
  const next = new Set();
103
- let node = hitTest(root, col, row) ?? undefined;
224
+ let node = hitTestWithOverlays(root, col, row) ?? undefined;
104
225
  while (node) {
105
226
  const h = node._eventHandlers;
106
227
  if (h?.onMouseEnter || h?.onMouseLeave)
@@ -112,15 +233,32 @@ export function dispatchHover(root, col, row, hovered) {
112
233
  hovered.delete(old);
113
234
  // Skip handlers on detached nodes (removed between mouse events)
114
235
  if (old.parentNode) {
115
- ;
116
- old._eventHandlers?.onMouseLeave?.();
236
+ const handler = old._eventHandlers
237
+ ?.onMouseLeave;
238
+ if (handler) {
239
+ try {
240
+ handler(new PointerEvent('hover', col, row, { action: 'move' }));
241
+ }
242
+ catch (error) {
243
+ logError(error);
244
+ }
245
+ }
117
246
  }
118
247
  }
119
248
  }
120
249
  for (const n of next) {
121
250
  if (!hovered.has(n)) {
122
251
  hovered.add(n);
123
- n._eventHandlers?.onMouseEnter?.();
252
+ const handler = n._eventHandlers
253
+ ?.onMouseEnter;
254
+ if (handler) {
255
+ try {
256
+ handler(new PointerEvent('hover', col, row, { action: 'move' }));
257
+ }
258
+ catch (error) {
259
+ logError(error);
260
+ }
261
+ }
124
262
  }
125
263
  }
126
264
  }
@@ -99,6 +99,28 @@ export default class Ink {
99
99
  reanchorViewport(): void;
100
100
  /** Render synchronously and invalidate older trailing/drain callbacks. */
101
101
  private renderNow;
102
+ /**
103
+ * Schedule the next scroll-drain frame — Grok Build's Presenter, ported.
104
+ * Grok keeps TWO cadence knobs (min_draw_ms for renders, scroll_ms for
105
+ * scroll); collapsing both to FRAME_INTERVAL_MS made big flicks steppy
106
+ * (the proportional step, 75%-of-remaining, × 4× the interval = chunky
107
+ * ramp and ~4× longer settle), so the drain keeps its own fast cadence:
108
+ *
109
+ * - CADENCE: quarter interval (~250fps). Drain frames are cheap
110
+ * (DECSTBM + ~10 patches); scroll throughput is unchanged.
111
+ * - IN-FLIGHT GATE: while stdout still holds unflushed bytes above
112
+ * PTY_BACKLOG_BYTES (slow ConPTY round trip, ssh link), queue nothing
113
+ * further — re-probe at quarter interval instead. Grok's equivalent
114
+ * (in_flight_target + writer ack) exists to keep latency bounded
115
+ * under exactly this backpressure; without it each stacked frame adds
116
+ * its full render+write to the input→paint latency, which reads as
117
+ * sticky, laggy scrolling on Windows terminals.
118
+ *
119
+ * The gate holds only DRAIN frames; React-driven renders (keystrokes,
120
+ * streaming) still render via the normal throttle — user-visible updates
121
+ * must never wait behind scroll output.
122
+ */
123
+ private scheduleDrain;
102
124
  onRender(): void;
103
125
  pause(): void;
104
126
  resume(): void;
@@ -193,6 +215,31 @@ export default class Ink {
193
215
  detachStdinForHandoff(): void;
194
216
  /** @see drainStdin */
195
217
  drainStdin(): void;
218
+ /**
219
+ * Self-heal after a terminal-side mode reset. Windows conpty drops DEC
220
+ * private modes on DPI changes, window moves between monitors and renderer
221
+ * restarts — the user sees the app "exit fullscreen" with a dead mouse
222
+ * while altScreenActive still claims we are in alt. Two layers:
223
+ *
224
+ * 1. Blind, idempotent mouse-tracking re-assert (covers the mode reset
225
+ * without a round trip; ~30 bytes).
226
+ * 2. DECRQM probe of mode 1049. Re-entry (destructive: ERASE) happens
227
+ * ONLY on a positive "reset" answer, so iTerm2's
228
+ * enter-clears-when-already-in-alt quirk can never fire on a healthy
229
+ * screen, and terminals that ignore DECRQM stay inert.
230
+ *
231
+ * Called from every interaction dispatch (click/hover/wheel/key) plus the
232
+ * focus/resize/stdin-gap triggers. The 250ms throttle keeps the round
233
+ * trip bounded while active use is going on — a dropped 1049 heals on
234
+ * the FIRST interaction after the drop instead of waiting for a focus
235
+ * event or a >5s idle gap (mouse motion keeps lastStdinTime fresh, so
236
+ * the gap path never fires during active use — the exact pattern that
237
+ * left the app broken until the user gave up).
238
+ */
239
+ private lastHealthProbeAt;
240
+ probeAltScreenHealth: () => void;
241
+ /** Refocus = first observable moment after a conpty-side mode reset. */
242
+ handleTerminalFocusProbe: (focused: boolean) => void;
196
243
  /**
197
244
  * Re-enter alt-screen, clear, home, re-enable mouse tracking, and reset
198
245
  * frame buffers so the next render repaints from scratch. Self-heal for
@@ -312,8 +359,18 @@ export default class Ink {
312
359
  * Returns true if a DOM handler consumed the click. Gated on
313
360
  * altScreenActive — clicks only make sense with a fixed viewport where
314
361
  * nodeCache rects map 1:1 to terminal cells (no scrollback offset).
362
+ * The button byte is the raw SGR release code; its modifier bits land
363
+ * on ClickEvent.shift/alt/ctrl.
364
+ */
365
+ dispatchClick(col: number, row: number, button?: number): boolean;
366
+ /**
367
+ * Route a wheel event to the ScrollBox (any onWheel handler) under the
368
+ * pointer. Returns true when a handler consumed it, so App can skip the
369
+ * legacy global wheel-key path and exactly one layer scrolls. Gated on
370
+ * altScreenActive like dispatchClick — without mouse tracking there are
371
+ * no wheel coordinates to route by.
315
372
  */
316
- dispatchClick(col: number, row: number): boolean;
373
+ dispatchWheelAt(col: number, row: number, deltaY: number, deltaX?: number, button?: number): boolean;
317
374
  dispatchHover(col: number, row: number): void;
318
375
  dispatchKeyboardEvent(parsedKey: ParsedKey): void;
319
376
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}