@reticlehq/browser 2.13.1 → 3.1.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 (244) hide show
  1. package/dist/actions/actions-dom.d.ts +8 -20
  2. package/dist/actions/actions-dom.js +70 -69
  3. package/dist/actions/actions-press.d.ts +14 -0
  4. package/dist/actions/actions-press.js +123 -0
  5. package/dist/actions/actions.d.ts +1 -89
  6. package/dist/actions/actions.js +64 -365
  7. package/dist/actions/appeared-text.d.ts +0 -20
  8. package/dist/actions/appeared-text.js +6 -36
  9. package/dist/actions/danger-context.d.ts +3 -0
  10. package/dist/actions/danger-context.js +39 -0
  11. package/dist/actions/scroll.d.ts +8 -10
  12. package/dist/actions/scroll.js +28 -17
  13. package/dist/actions/synthetic/synthetic-input.d.ts +2 -0
  14. package/dist/actions/synthetic/synthetic-input.js +13 -0
  15. package/dist/actions/value-input.d.ts +0 -30
  16. package/dist/actions/value-input.js +0 -33
  17. package/dist/commands/commands.d.ts +0 -2
  18. package/dist/commands/commands.js +10 -70
  19. package/dist/connect-options.d.ts +2 -96
  20. package/dist/dom/a11y.d.ts +0 -29
  21. package/dist/dom/a11y.js +3 -90
  22. package/dist/dom/addressing/auto-anchor.d.ts +25 -0
  23. package/dist/dom/addressing/auto-anchor.js +41 -0
  24. package/dist/dom/addressing/refs.d.ts +14 -0
  25. package/dist/dom/addressing/refs.js +114 -0
  26. package/dist/dom/addressing/source.d.ts +9 -0
  27. package/dist/dom/addressing/source.js +29 -0
  28. package/dist/dom/chart.d.ts +0 -61
  29. package/dist/dom/chart.js +0 -60
  30. package/dist/dom/desktop-capture.d.ts +0 -30
  31. package/dist/dom/desktop-capture.js +1 -73
  32. package/dist/dom/dom-ignore.d.ts +0 -30
  33. package/dist/dom/dom-ignore.js +1 -48
  34. package/dist/dom/occlusion.d.ts +0 -7
  35. package/dist/dom/occlusion.js +31 -12
  36. package/dist/dom/paint-context.d.ts +6 -0
  37. package/dist/dom/paint-context.js +38 -0
  38. package/dist/dom/query.d.ts +0 -14
  39. package/dist/dom/query.js +50 -216
  40. package/dist/dom/realm.d.ts +0 -20
  41. package/dist/dom/realm.js +0 -28
  42. package/dist/dom/shadow-registry.d.ts +0 -33
  43. package/dist/dom/shadow-registry.js +2 -72
  44. package/dist/dom/snapshot.d.ts +2 -43
  45. package/dist/dom/snapshot.js +27 -152
  46. package/dist/dom/theme.d.ts +0 -37
  47. package/dist/dom/theme.js +2 -52
  48. package/dist/dom/virtualized.d.ts +0 -17
  49. package/dist/dom/virtualized.js +0 -27
  50. package/dist/edit-epoch.d.ts +1 -23
  51. package/dist/edit-epoch.js +1 -53
  52. package/dist/index.d.ts +4 -5
  53. package/dist/index.js +4 -28
  54. package/dist/observers/animation.d.ts +0 -1
  55. package/dist/observers/animation.js +1 -4
  56. package/dist/observers/blind-spots.d.ts +0 -26
  57. package/dist/observers/blind-spots.js +3 -62
  58. package/dist/observers/console.d.ts +1 -2
  59. package/dist/observers/console.js +41 -30
  60. package/dist/observers/context-open.d.ts +1 -11
  61. package/dist/observers/context-open.js +10 -14
  62. package/dist/observers/departure.d.ts +3 -0
  63. package/dist/observers/departure.js +52 -0
  64. package/dist/observers/dialogs.d.ts +2 -0
  65. package/dist/observers/dialogs.js +39 -0
  66. package/dist/observers/dom.js +28 -52
  67. package/dist/observers/download.d.ts +1 -2
  68. package/dist/observers/download.js +39 -56
  69. package/dist/observers/focus.d.ts +0 -6
  70. package/dist/observers/focus.js +0 -7
  71. package/dist/observers/frames.d.ts +0 -9
  72. package/dist/observers/frames.js +1 -28
  73. package/dist/observers/health.d.ts +0 -5
  74. package/dist/observers/health.js +2 -34
  75. package/dist/observers/install-all.d.ts +2 -0
  76. package/dist/observers/install-all.js +26 -27
  77. package/dist/observers/ipc.d.ts +0 -25
  78. package/dist/observers/ipc.js +0 -65
  79. package/dist/observers/navigation.d.ts +2 -0
  80. package/dist/observers/navigation.js +33 -0
  81. package/dist/observers/net-detail/network-body.d.ts +12 -0
  82. package/dist/observers/net-detail/network-body.js +71 -0
  83. package/dist/observers/net-detail/network-redact.d.ts +1 -0
  84. package/dist/observers/net-detail/network-redact.js +1 -0
  85. package/dist/observers/network-stream.d.ts +0 -21
  86. package/dist/observers/network-stream.js +3 -46
  87. package/dist/observers/network.d.ts +3 -27
  88. package/dist/observers/network.js +178 -295
  89. package/dist/observers/perf.d.ts +0 -10
  90. package/dist/observers/perf.js +0 -16
  91. package/dist/observers/route.d.ts +1 -2
  92. package/dist/observers/route.js +13 -19
  93. package/dist/observers/scroll.d.ts +0 -1
  94. package/dist/observers/scroll.js +2 -11
  95. package/dist/observers/sdk-failure.d.ts +1 -9
  96. package/dist/observers/sdk-failure.js +1 -30
  97. package/dist/observers/state.d.ts +1 -11
  98. package/dist/observers/state.js +13 -41
  99. package/dist/observers/storage.d.ts +0 -14
  100. package/dist/observers/storage.js +10 -34
  101. package/dist/observers/types.d.ts +0 -15
  102. package/dist/observers/types.js +0 -14
  103. package/dist/patching/capture-method.d.ts +0 -24
  104. package/dist/patching/capture-method.js +0 -26
  105. package/dist/presenter/chrome/layers.d.ts +2 -0
  106. package/dist/presenter/chrome/layers.js +2 -0
  107. package/dist/presenter/chrome/log-kinds.d.ts +12 -0
  108. package/dist/presenter/chrome/log-kinds.js +7 -0
  109. package/dist/presenter/{overlay.d.ts → chrome/overlay.d.ts} +0 -1
  110. package/dist/presenter/{overlay.js → chrome/overlay.js} +0 -1
  111. package/dist/presenter/chrome/presenter-brand.d.ts +3 -0
  112. package/dist/presenter/{presenter-brand.js → chrome/presenter-brand.js} +0 -21
  113. package/dist/presenter/chrome/presenter-effects.d.ts +4 -0
  114. package/dist/presenter/{presenter-effects.js → chrome/presenter-effects.js} +1 -10
  115. package/dist/presenter/chrome/presenter-hud-chrome.d.ts +7 -0
  116. package/dist/presenter/{presenter-hud-chrome.js → chrome/presenter-hud-chrome.js} +0 -10
  117. package/dist/presenter/chrome/presenter-log.d.ts +17 -0
  118. package/dist/presenter/{presenter-log.js → chrome/presenter-log.js} +5 -54
  119. package/dist/presenter/chrome/presenter-report-copy.d.ts +51 -0
  120. package/dist/presenter/chrome/presenter-report-copy.js +95 -0
  121. package/dist/presenter/chrome/presenter-safe-html.d.ts +2 -0
  122. package/dist/presenter/chrome/presenter-safe-html.js +16 -0
  123. package/dist/presenter/{presenter-tally.d.ts → chrome/presenter-tally.d.ts} +0 -5
  124. package/dist/presenter/{presenter-tally.js → chrome/presenter-tally.js} +1 -5
  125. package/dist/presenter/{presenter-verbs.js → chrome/presenter-verbs.js} +0 -7
  126. package/dist/presenter/{presenter-heroicons-data.d.ts → icons/presenter-heroicons-data.d.ts} +1 -8
  127. package/dist/presenter/{presenter-heroicons-data.js → icons/presenter-heroicons-data.js} +1 -8
  128. package/dist/presenter/{presenter-icons.d.ts → icons/presenter-icons.d.ts} +1 -6
  129. package/dist/presenter/{presenter-icons.js → icons/presenter-icons.js} +1 -6
  130. package/dist/presenter/presenter-account-styles.d.ts +1 -0
  131. package/dist/presenter/presenter-account-styles.js +99 -0
  132. package/dist/presenter/presenter-account.d.ts +40 -0
  133. package/dist/presenter/presenter-account.js +178 -0
  134. package/dist/presenter/presenter-config.d.ts +10 -107
  135. package/dist/presenter/presenter-config.js +5 -92
  136. package/dist/presenter/presenter-controls.d.ts +1 -35
  137. package/dist/presenter/presenter-controls.js +10 -133
  138. package/dist/presenter/presenter-dock-layout.d.ts +0 -3
  139. package/dist/presenter/presenter-dock-layout.js +1 -5
  140. package/dist/presenter/presenter-drag.d.ts +2 -42
  141. package/dist/presenter/presenter-drag.js +3 -76
  142. package/dist/presenter/presenter-glow.d.ts +0 -21
  143. package/dist/presenter/presenter-glow.js +2 -28
  144. package/dist/presenter/presenter-hud-position.d.ts +18 -0
  145. package/dist/presenter/presenter-hud-position.js +50 -0
  146. package/dist/presenter/presenter-report-styles.d.ts +0 -6
  147. package/dist/presenter/presenter-report-styles.js +22 -7
  148. package/dist/presenter/presenter-report.d.ts +5 -7
  149. package/dist/presenter/presenter-report.js +44 -95
  150. package/dist/presenter/presenter-run-state.d.ts +1 -8
  151. package/dist/presenter/presenter-run-state.js +1 -6
  152. package/dist/presenter/presenter-settings-styles.d.ts +0 -1
  153. package/dist/presenter/presenter-settings-styles.js +2 -2
  154. package/dist/presenter/presenter-settings.d.ts +5 -23
  155. package/dist/presenter/presenter-settings.js +21 -33
  156. package/dist/presenter/presenter-shell-styles.js +23 -20
  157. package/dist/presenter/presenter-shell.d.ts +6 -18
  158. package/dist/presenter/presenter-shell.js +26 -77
  159. package/dist/presenter/presenter-styles.d.ts +2 -10
  160. package/dist/presenter/presenter-styles.js +6 -12
  161. package/dist/presenter/presenter-workspace.d.ts +4 -4
  162. package/dist/presenter/presenter-workspace.js +30 -10
  163. package/dist/presenter/presenter.d.ts +3 -63
  164. package/dist/presenter/presenter.js +29 -132
  165. package/dist/presenter/tour/tour-view.d.ts +33 -0
  166. package/dist/presenter/tour/tour-view.js +188 -0
  167. package/dist/presenter/tour/tour.d.ts +25 -0
  168. package/dist/presenter/tour/tour.js +245 -0
  169. package/dist/recorder/recorder-styles.d.ts +0 -6
  170. package/dist/recorder/recorder-styles.js +0 -6
  171. package/dist/recorder/recorder.d.ts +0 -34
  172. package/dist/recorder/recorder.js +6 -49
  173. package/dist/registry/auto-testids.d.ts +0 -19
  174. package/dist/registry/auto-testids.js +1 -21
  175. package/dist/registry/capabilities.d.ts +0 -31
  176. package/dist/registry/capabilities.js +1 -46
  177. package/dist/registry/commit-and-signal.d.ts +0 -6
  178. package/dist/registry/commit-and-signal.js +1 -7
  179. package/dist/registry/declared-channels.d.ts +2 -0
  180. package/dist/registry/declared-channels.js +14 -0
  181. package/dist/registry/declared-platform.d.ts +4 -0
  182. package/dist/registry/declared-platform.js +34 -0
  183. package/dist/registry/domains.d.ts +0 -8
  184. package/dist/registry/domains.js +0 -7
  185. package/dist/registry/emitter.d.ts +0 -14
  186. package/dist/registry/emitter.js +1 -11
  187. package/dist/registry/store-adapters.d.ts +0 -186
  188. package/dist/registry/store-adapters.js +1 -164
  189. package/dist/registry/{adapters.d.ts → stores/adapters.d.ts} +0 -10
  190. package/dist/registry/{adapters.js → stores/adapters.js} +0 -10
  191. package/dist/registry/stores.d.ts +0 -33
  192. package/dist/registry/stores.js +1 -60
  193. package/dist/reticle-presenter-helpers.d.ts +0 -13
  194. package/dist/reticle-presenter-helpers.js +10 -20
  195. package/dist/reticle-singleton.d.ts +2 -0
  196. package/dist/reticle-singleton.js +3 -0
  197. package/dist/reticle.d.ts +1 -52
  198. package/dist/reticle.js +115 -180
  199. package/dist/review/annotator-styles.js +1 -8
  200. package/dist/review/annotator.d.ts +2 -13
  201. package/dist/review/annotator.js +2 -42
  202. package/dist/review/mark-anchor.d.ts +0 -11
  203. package/dist/review/mark-anchor.js +3 -11
  204. package/dist/security/serialization.d.ts +0 -20
  205. package/dist/security/serialization.js +1 -66
  206. package/dist/session-continuity.d.ts +0 -16
  207. package/dist/session-continuity.js +1 -20
  208. package/dist/timers/clock.d.ts +1 -14
  209. package/dist/timers/clock.js +59 -60
  210. package/dist/timers/console/native-console.js +5 -0
  211. package/dist/timers/native/native-timers.d.ts +11 -0
  212. package/dist/timers/native/native-timers.js +48 -0
  213. package/dist/transport/transport.d.ts +0 -51
  214. package/dist/transport/transport.js +5 -131
  215. package/dist/transport/unreachable-message.d.ts +0 -17
  216. package/dist/transport/unreachable-message.js +0 -17
  217. package/dist/util/captured-method.d.ts +0 -35
  218. package/dist/util/captured-method.js +0 -35
  219. package/package.json +5 -4
  220. package/dist/actions/synthetic-input.d.ts +0 -9
  221. package/dist/actions/synthetic-input.js +0 -40
  222. package/dist/dom/auto-anchor.d.ts +0 -65
  223. package/dist/dom/auto-anchor.js +0 -74
  224. package/dist/dom/refs.d.ts +0 -90
  225. package/dist/dom/refs.js +0 -245
  226. package/dist/dom/source.d.ts +0 -53
  227. package/dist/dom/source.js +0 -74
  228. package/dist/observers/network-body.d.ts +0 -35
  229. package/dist/observers/network-body.js +0 -168
  230. package/dist/observers/network-redact.d.ts +0 -20
  231. package/dist/observers/network-redact.js +0 -80
  232. package/dist/presenter/presenter-brand.d.ts +0 -22
  233. package/dist/presenter/presenter-effects.d.ts +0 -13
  234. package/dist/presenter/presenter-hud-chrome.d.ts +0 -17
  235. package/dist/presenter/presenter-log.d.ts +0 -64
  236. package/dist/presenter/presenter-report-copy.d.ts +0 -112
  237. package/dist/presenter/presenter-report-copy.js +0 -156
  238. package/dist/presenter/presenter-test-helpers.d.ts +0 -16
  239. package/dist/presenter/presenter-test-helpers.js +0 -41
  240. package/dist/timers/native-console.js +0 -9
  241. package/dist/timers/native-timers.d.ts +0 -36
  242. package/dist/timers/native-timers.js +0 -78
  243. /package/dist/presenter/{presenter-verbs.d.ts → chrome/presenter-verbs.d.ts} +0 -0
  244. /package/dist/timers/{native-console.d.ts → console/native-console.d.ts} +0 -0
@@ -0,0 +1,99 @@
1
+ import { HUD_DROP_SHADOW, HUD_SURFACE_PAINT } from './chrome/presenter-hud-chrome.js';
2
+ const AVATAR = 20;
3
+ const AVATAR_LG = 28;
4
+ export const ACCOUNT_CSS = `
5
+ /* The control establishes its own stacking context, and a high one.
6
+ Its menu is absolutely positioned inside a panel whose other children (the log well, the act strip)
7
+ are themselves positioned with their own z-index, so a z-index on the MENU alone was being compared
8
+ inside the wrong context and lost to a sibling with a lower number. Raising it here, on the thing
9
+ that contains the menu, is what actually puts the menu above them. 9 clears the workspace menu's 8,
10
+ which is the highest in-panel chrome. */
11
+ /* The header row has to out-stack the log well, or nothing inside it can.
12
+ .reticle-chat-head is position:relative with z-index:2, so it IS a stacking context and the number
13
+ below is scoped inside it -- while the log well is a SIBLING, also at z-index:2, and later in DOM
14
+ order. Equal z, later sibling wins, so the well painted over the whole header and took the open
15
+ menu with it. The menu measured correctly and was invisible, which is the shape of bug that reads
16
+ as "the dropdown does not work". Raising the header is what lets its children escape; the two only
17
+ overlap while a menu is open, so nothing else moves. */
18
+ .reticle-chat-head{z-index:3;}
19
+ .reticle-account{position:relative;z-index:9;display:inline-flex;align-items:center;gap:6px;flex:none;}
20
+ .reticle-account-avatar{
21
+ display:inline-flex;align-items:center;justify-content:center;
22
+ width:${String(AVATAR)}px;height:${String(AVATAR)}px;border-radius:999px;
23
+ font-size:9px;font-weight:600;letter-spacing:.02em;
24
+ background:rgba(255,255,255,.12);color:rgba(255,255,255,.92);user-select:none;}
25
+ .reticle-account-avatar--lg{
26
+ width:${String(AVATAR_LG)}px;height:${String(AVATAR_LG)}px;font-size:11px;}
27
+
28
+ /* The trigger is the avatar plus a hit area, never a second visual element: an avatar that looks
29
+ like a button reads as an action, and this one opens a menu about a state. */
30
+ .reticle-account-trigger{
31
+ display:inline-flex;align-items:center;justify-content:center;
32
+ padding:0;border:none;background:transparent;cursor:pointer;line-height:0;border-radius:999px;
33
+ transition:box-shadow .12s,opacity .12s;}
34
+ .reticle-account-trigger:hover{opacity:.85;}
35
+ .reticle-account-trigger:focus-visible{outline:none;box-shadow:0 0 0 2px rgba(255,255,255,.35);}
36
+ .reticle-account-trigger[aria-expanded="true"]{box-shadow:0 0 0 2px rgba(255,255,255,.28);}
37
+
38
+ .reticle-account-signin{
39
+ border:none;border-radius:6px;padding:2px 9px;cursor:pointer;font:inherit;font-size:10.5px;
40
+ background:rgba(255,255,255,.06);color:rgba(255,255,255,.75);transition:background .12s,color .12s;}
41
+ .reticle-account-signin:hover{background:rgba(255,255,255,.12);color:#fff;}
42
+
43
+ /* Anchored to the control and opening DOWNWARD.
44
+ Not upward, which is what it looked like it wanted: all three surfaces mount this near the TOP of
45
+ a panel whose own overflow is hidden for its rounded corners, so a menu opening upward is laid
46
+ out correctly and then clipped away entirely -- present to the probe, invisible to the eye. Panels
47
+ grow downward and have the height, so down is the direction that stays inside the box. */
48
+ .reticle-account-menu{
49
+ position:absolute;right:0;top:calc(100% + 8px);z-index:6;
50
+ min-width:212px;max-width:280px;padding:10px;box-sizing:border-box;
51
+ display:flex;flex-direction:column;gap:8px;
52
+ border-radius:10px;
53
+ /* The HUD's own surface tokens, not a colour invented here. A menu with its own near-black is a
54
+ second design language in the same panel, and a translucent one lets the panel's empty-state text
55
+ read straight through the rows -- which is what the first version did. */
56
+ ${HUD_SURFACE_PAINT}
57
+ box-shadow:inset 0 1px 0 rgba(255,255,255,.09),${HUD_DROP_SHADOW};
58
+ font-size:11px;color:rgba(255,255,255,.78);text-align:left;}
59
+ .reticle-account-menu[hidden]{display:none;}
60
+
61
+ .reticle-account-head{display:flex;align-items:center;gap:8px;min-width:0;}
62
+ .reticle-account-who{display:flex;flex-direction:column;min-width:0;gap:1px;}
63
+ .reticle-account-org{
64
+ font-size:11.5px;font-weight:600;color:rgba(255,255,255,.95);
65
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
66
+ .reticle-account-email{
67
+ font-size:10.5px;color:rgba(255,255,255,.55);
68
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
69
+
70
+ .reticle-account-rows{
71
+ display:flex;flex-direction:column;gap:4px;
72
+ padding-top:8px;border-top:1px solid rgba(255,255,255,.08);}
73
+ .reticle-account-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
74
+ .reticle-account-k{color:rgba(255,255,255,.5);flex:none;}
75
+ .reticle-account-v{
76
+ color:rgba(255,255,255,.88);min-width:0;
77
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
78
+ font-variant-numeric:tabular-nums;}
79
+
80
+ .reticle-account-actions{
81
+ display:flex;flex-direction:column;gap:2px;
82
+ padding-top:8px;border-top:1px solid rgba(255,255,255,.08);}
83
+ .reticle-account-action{
84
+ display:flex;align-items:center;gap:6px;width:100%;box-sizing:border-box;
85
+ padding:5px 6px;border:none;border-radius:6px;cursor:pointer;
86
+ font:inherit;font-size:11px;text-align:left;text-decoration:none;
87
+ background:transparent;color:rgba(255,255,255,.8);transition:background .12s,color .12s;}
88
+ .reticle-account-action:hover{background:rgba(255,255,255,.08);color:#fff;}
89
+ .reticle-account-action:focus-visible{outline:none;background:rgba(255,255,255,.1);color:#fff;}
90
+ /* The unlinked hint is a sentence, not a verb: it wraps rather than truncating, because a clipped
91
+ instruction is worse than a tall menu. */
92
+ .reticle-account-action--hint{
93
+ color:rgba(255,255,255,.5);font-size:10.5px;line-height:1.35;white-space:normal;cursor:pointer;}
94
+
95
+ .reticle-account-dashboard{
96
+ display:inline-flex;align-items:center;justify-content:center;
97
+ border:none;background:transparent;color:rgba(255,255,255,.6);cursor:pointer;line-height:0;padding:2px;}
98
+ .reticle-account-dashboard:hover{color:#fff;}
99
+ `;
@@ -0,0 +1,40 @@
1
+ import type { AccountState } from '@reticlehq/core';
2
+ export declare const ACCOUNT_ROOT_ATTR = "data-reticle-account";
3
+ export declare const ACCOUNT_SIGNIN_ATTR = "data-reticle-account-signin";
4
+ export declare const SYNC_BTN_ATTR = "data-reticle-sync-now";
5
+ export declare const ACCOUNT_TRIGGER_ATTR = "data-reticle-account-trigger";
6
+ export declare const ACCOUNT_MENU_ATTR = "data-reticle-account-menu";
7
+ export declare const ACCOUNT_SIGNOUT_ATTR = "data-reticle-account-signout";
8
+ export declare const ACCOUNT_TEXT: {
9
+ readonly SIGNED_OUT: "Sign in";
10
+ readonly SIGNIN_TITLE: "Run `reticle login` in your terminal — click to copy the command";
11
+ readonly SIGNIN_COMMAND: "reticle login";
12
+ readonly DASHBOARD_TITLE: "Open this project on the dashboard";
13
+ readonly SYNC_TITLE: "Push to the dashboard now, instead of waiting for the next sync";
14
+ readonly COPIED: "Copied";
15
+ readonly AVATAR_FALLBACK: "•";
16
+ readonly MENU_LABEL: "Reticle account";
17
+ readonly TRIGGER_TITLE: "Your Reticle account";
18
+ readonly SIGNED_IN_AS: "Signed in";
19
+ readonly DASHBOARD_ACTION: "Open dashboard";
20
+ readonly LINK_HINT: "Not linked — run `reticle link` to keep a record on the dashboard";
21
+ readonly LINK_COMMAND: "reticle link";
22
+ readonly SIGNOUT_ACTION: "Sign out";
23
+ readonly SIGNOUT_TITLE: "Run `reticle logout` in your terminal — click to copy the command";
24
+ readonly SIGNOUT_COMMAND: "reticle logout";
25
+ readonly PROJECT_LABEL: "Project";
26
+ readonly HOST_LABEL: "Host";
27
+ readonly VERDICTS_LABEL: "Verdicts";
28
+ readonly DEFECTS_LABEL: "Defects found";
29
+ };
30
+ export interface AccountDetails {
31
+ projectName?: string | undefined;
32
+ dashboardUrl?: string | undefined;
33
+ verdicts?: number | undefined;
34
+ defects?: number | undefined;
35
+ }
36
+ export declare function accountInitials(org: string | undefined): string;
37
+ export declare function accountControlHtml(account: AccountState | undefined, details?: AccountDetails, offerSignIn?: boolean): string;
38
+ export declare function accountCapsuleHtml(account: AccountState | undefined, dashboardUrl?: string, offerSignIn?: boolean): string;
39
+ export declare function syncButtonHtml(dashboardUrl: string | undefined): string;
40
+ export declare function mountAccountControl(root: HTMLElement): () => void;
@@ -0,0 +1,178 @@
1
+ import { hiIconHtml, PRESENTER_ICON_SIZE, PresenterIcon } from './icons/presenter-icons.js';
2
+ import { esc, isSafeDashboardUrl } from './chrome/presenter-safe-html.js';
3
+ export const ACCOUNT_ROOT_ATTR = 'data-reticle-account';
4
+ export const ACCOUNT_SIGNIN_ATTR = 'data-reticle-account-signin';
5
+ export const SYNC_BTN_ATTR = 'data-reticle-sync-now';
6
+ export const ACCOUNT_TRIGGER_ATTR = 'data-reticle-account-trigger';
7
+ export const ACCOUNT_MENU_ATTR = 'data-reticle-account-menu';
8
+ export const ACCOUNT_SIGNOUT_ATTR = 'data-reticle-account-signout';
9
+ export const ACCOUNT_TEXT = {
10
+ SIGNED_OUT: 'Sign in',
11
+ SIGNIN_TITLE: 'Run `reticle login` in your terminal — click to copy the command',
12
+ SIGNIN_COMMAND: 'reticle login',
13
+ DASHBOARD_TITLE: 'Open this project on the dashboard',
14
+ SYNC_TITLE: 'Push to the dashboard now, instead of waiting for the next sync',
15
+ COPIED: 'Copied',
16
+ AVATAR_FALLBACK: '•',
17
+ MENU_LABEL: 'Reticle account',
18
+ TRIGGER_TITLE: 'Your Reticle account',
19
+ SIGNED_IN_AS: 'Signed in',
20
+ DASHBOARD_ACTION: 'Open dashboard',
21
+ LINK_HINT: 'Not linked — run `reticle link` to keep a record on the dashboard',
22
+ LINK_COMMAND: 'reticle link',
23
+ SIGNOUT_ACTION: 'Sign out',
24
+ SIGNOUT_TITLE: 'Run `reticle logout` in your terminal — click to copy the command',
25
+ SIGNOUT_COMMAND: 'reticle logout',
26
+ PROJECT_LABEL: 'Project',
27
+ HOST_LABEL: 'Host',
28
+ VERDICTS_LABEL: 'Verdicts',
29
+ DEFECTS_LABEL: 'Defects found',
30
+ };
31
+ const ACCOUNT_COPIED_MS = 1200;
32
+ export function accountInitials(org) {
33
+ const words = (org ?? '')
34
+ .trim()
35
+ .split(/[\s._-]+/)
36
+ .filter((word) => word.length > 0);
37
+ const letters = words
38
+ .slice(0, 2)
39
+ .map((word) => [...word][0] ?? '')
40
+ .join('');
41
+ return letters.length > 0 ? letters.toUpperCase() : ACCOUNT_TEXT.AVATAR_FALLBACK;
42
+ }
43
+ export function accountControlHtml(account, details = {}, offerSignIn = false) {
44
+ if (account === undefined)
45
+ return '';
46
+ if (!account.signedIn) {
47
+ if (!offerSignIn)
48
+ return '';
49
+ return `<div class="reticle-account" ${ACCOUNT_ROOT_ATTR}><button type="button" class="reticle-account-signin" ${ACCOUNT_SIGNIN_ATTR} title="${ACCOUNT_TEXT.SIGNIN_TITLE}" aria-label="${ACCOUNT_TEXT.SIGNIN_TITLE}">${ACCOUNT_TEXT.SIGNED_OUT}</button></div>`;
50
+ }
51
+ const org = account.org ?? '';
52
+ const label = org.length > 0 ? esc(org) : ACCOUNT_TEXT.SIGNED_IN_AS;
53
+ const avatar = `<span class="reticle-account-avatar" aria-hidden="true">${esc(accountInitials(account.org))}</span>`;
54
+ const trigger = `<button type="button" class="reticle-account-trigger" ${ACCOUNT_TRIGGER_ATTR}` +
55
+ ` aria-haspopup="true" aria-expanded="false" title="${ACCOUNT_TEXT.TRIGGER_TITLE}"` +
56
+ ` aria-label="${ACCOUNT_TEXT.TRIGGER_TITLE}: ${label}">${avatar}</button>`;
57
+ return `<div class="reticle-account" ${ACCOUNT_ROOT_ATTR}>${trigger}${accountMenuHtml(account, details)}</div>`;
58
+ }
59
+ function detailRow(key, value) {
60
+ if (value === undefined || 0 === value.length)
61
+ return '';
62
+ return `<div class="reticle-account-row"><span class="reticle-account-k">${esc(key)}</span><span class="reticle-account-v" title="${esc(value)}">${esc(value)}</span></div>`;
63
+ }
64
+ function accountMenuHtml(account, details) {
65
+ const org = account.org ?? '';
66
+ const identity = `<div class="reticle-account-head">` +
67
+ `<span class="reticle-account-avatar reticle-account-avatar--lg" aria-hidden="true">${esc(accountInitials(account.org))}</span>` +
68
+ `<span class="reticle-account-who">` +
69
+ `<span class="reticle-account-org">${org.length > 0 ? esc(org) : ACCOUNT_TEXT.SIGNED_IN_AS}</span>` +
70
+ (account.email !== undefined && account.email.length > 0
71
+ ? `<span class="reticle-account-email" title="${esc(account.email)}">${esc(account.email)}</span>`
72
+ : `<span class="reticle-account-email">${ACCOUNT_TEXT.SIGNED_IN_AS}</span>`) +
73
+ `</span></div>`;
74
+ const rows = detailRow(ACCOUNT_TEXT.HOST_LABEL, account.host) +
75
+ detailRow(ACCOUNT_TEXT.PROJECT_LABEL, details.projectName) +
76
+ detailRow(ACCOUNT_TEXT.VERDICTS_LABEL, details.verdicts !== undefined ? String(details.verdicts) : undefined) +
77
+ detailRow(ACCOUNT_TEXT.DEFECTS_LABEL, details.defects !== undefined ? String(details.defects) : undefined);
78
+ const linked = details.dashboardUrl !== undefined && isSafeDashboardUrl(details.dashboardUrl);
79
+ const dashboard = linked
80
+ ? `<a class="reticle-account-action" href="${esc(details.dashboardUrl ?? '')}" target="_blank" rel="noreferrer noopener" title="${ACCOUNT_TEXT.DASHBOARD_TITLE}">${hiIconHtml(PresenterIcon.VIEW, PRESENTER_ICON_SIZE.HELP)}<span>${ACCOUNT_TEXT.DASHBOARD_ACTION}</span></a>`
81
+ :
82
+ `<button type="button" class="reticle-account-action reticle-account-action--hint" ${ACCOUNT_SIGNIN_ATTR} data-reticle-copy="${ACCOUNT_TEXT.LINK_COMMAND}" title="${ACCOUNT_TEXT.LINK_HINT}"><span>${ACCOUNT_TEXT.LINK_HINT}</span></button>`;
83
+ const signOut = `<button type="button" class="reticle-account-action" ${ACCOUNT_SIGNOUT_ATTR} data-reticle-copy="${ACCOUNT_TEXT.SIGNOUT_COMMAND}" title="${ACCOUNT_TEXT.SIGNOUT_TITLE}"><span>${ACCOUNT_TEXT.SIGNOUT_ACTION}</span></button>`;
84
+ return (`<div class="reticle-account-menu" ${ACCOUNT_MENU_ATTR} role="menu" aria-label="${ACCOUNT_TEXT.MENU_LABEL}" aria-hidden="true" hidden>` +
85
+ identity +
86
+ (rows.length > 0 ? `<div class="reticle-account-rows">${rows}</div>` : '') +
87
+ `<div class="reticle-account-actions">${dashboard}${signOut}</div>` +
88
+ `</div>`);
89
+ }
90
+ export function accountCapsuleHtml(account, dashboardUrl, offerSignIn = false) {
91
+ return accountControlHtml(account, { dashboardUrl }, offerSignIn);
92
+ }
93
+ export function syncButtonHtml(dashboardUrl) {
94
+ if (dashboardUrl === undefined || !isSafeDashboardUrl(dashboardUrl))
95
+ return '';
96
+ return `<button type="button" class="reticle-sync-now" ${SYNC_BTN_ATTR} title="${ACCOUNT_TEXT.SYNC_TITLE}" aria-label="${ACCOUNT_TEXT.SYNC_TITLE}">${hiIconHtml(PresenterIcon.SYNC, PRESENTER_ICON_SIZE.HELP)}</button>`;
97
+ }
98
+ export function mountAccountControl(root) {
99
+ const controller = new AbortController();
100
+ const { signal } = controller;
101
+ const closeAll = (except) => {
102
+ for (const menu of root.querySelectorAll(`[${ACCOUNT_MENU_ATTR}]`)) {
103
+ if (menu === except)
104
+ continue;
105
+ menu.setAttribute('hidden', '');
106
+ menu.setAttribute('aria-hidden', 'true');
107
+ }
108
+ for (const trigger of root.querySelectorAll(`[${ACCOUNT_TRIGGER_ATTR}]`)) {
109
+ if (except !== undefined && trigger.parentElement === except.parentElement)
110
+ continue;
111
+ trigger.setAttribute('aria-expanded', 'false');
112
+ }
113
+ };
114
+ const flashCopied = (el) => {
115
+ const label = el.querySelector('span') ?? el;
116
+ const previous = label.textContent;
117
+ label.textContent = ACCOUNT_TEXT.COPIED;
118
+ setTimeout(() => {
119
+ label.textContent = previous;
120
+ }, ACCOUNT_COPIED_MS);
121
+ };
122
+ root.addEventListener('click', (event) => {
123
+ const target = event.target;
124
+ if (!(target instanceof Element))
125
+ return;
126
+ const trigger = target.closest(`[${ACCOUNT_TRIGGER_ATTR}]`);
127
+ if (trigger instanceof HTMLElement) {
128
+ event.preventDefault();
129
+ event.stopPropagation();
130
+ const menu = trigger.parentElement?.querySelector(`[${ACCOUNT_MENU_ATTR}]`);
131
+ if (!(menu instanceof HTMLElement))
132
+ return;
133
+ const wasOpen = !menu.hasAttribute('hidden');
134
+ closeAll();
135
+ if (wasOpen)
136
+ return;
137
+ menu.removeAttribute('hidden');
138
+ menu.setAttribute('aria-hidden', 'false');
139
+ trigger.setAttribute('aria-expanded', 'true');
140
+ return;
141
+ }
142
+ const copier = target.closest('[data-reticle-copy]');
143
+ if (copier instanceof HTMLElement) {
144
+ event.preventDefault();
145
+ event.stopPropagation();
146
+ const command = copier.getAttribute('data-reticle-copy') ?? '';
147
+ if (command.length > 0)
148
+ void navigator.clipboard?.writeText(command).catch(() => undefined);
149
+ flashCopied(copier);
150
+ return;
151
+ }
152
+ const signin = target.closest(`[${ACCOUNT_SIGNIN_ATTR}]`);
153
+ if (signin instanceof HTMLElement) {
154
+ event.preventDefault();
155
+ event.stopPropagation();
156
+ void navigator.clipboard?.writeText(ACCOUNT_TEXT.SIGNIN_COMMAND).catch(() => undefined);
157
+ flashCopied(signin);
158
+ return;
159
+ }
160
+ closeAll();
161
+ }, { signal });
162
+ document.addEventListener('pointerdown', (event) => {
163
+ const target = event.target;
164
+ if (target instanceof Node && root.contains(target))
165
+ return;
166
+ closeAll();
167
+ }, { signal });
168
+ document.addEventListener('keydown', (event) => {
169
+ if ('Escape' !== event.key)
170
+ return;
171
+ const open = root.querySelector(`[${ACCOUNT_MENU_ATTR}]:not([hidden])`);
172
+ if (null === open)
173
+ return;
174
+ event.stopPropagation();
175
+ closeAll();
176
+ }, { signal });
177
+ return () => controller.abort();
178
+ }
@@ -1,14 +1,4 @@
1
- import type { ControlHandler } from './presenter-controls.js';
2
- /**
3
- * Presenter tunables + option surface. Split out of presenter.ts so that file is just the controller
4
- * under the size cap; these are pure declarations (interfaces + named constants), no behavior. None
5
- * cross the browser↔bridge↔agent wire, so they live here, not in @reticlehq/core.
6
- */
7
- /**
8
- * Border behavior.
9
- * - 'session': base border persists connect→disconnect; the busy machine drives only the shimmer.
10
- * - 'busy': back-compat - the busy machine toggles the base border on/off.
11
- */
1
+ import type { HumanControlKind } from '@reticlehq/core';
12
2
  export declare const BorderMode: {
13
3
  readonly SESSION: "session";
14
4
  readonly BUSY: "busy";
@@ -20,179 +10,92 @@ export declare const BUSY_ON = "1";
20
10
  export declare const BUSY_OFF = "0";
21
11
  export interface PresenterOptions {
22
12
  paceMs?: number;
23
- /** Injected monotonic clock for the glow state machine (tests drive transitions). */
24
13
  now?: () => number;
25
- /** Quiet window before busy -> fading. Overridable so tests run fast. */
26
14
  idleAfterMs?: number;
27
- /** Fade duration before fading -> idle (keep in sync with the glow CSS opacity transition). */
28
15
  glowFadeMs?: number;
29
- /** Liveness heartbeat interval (ms). Overridable so tests run fast. */
30
16
  heartbeatMs?: number;
31
- /** Quiet (ms) after which the act strip shows the live "idle · {duration}" clock. Test-overridable. */
32
17
  idleNoticeMs?: number;
33
- /** Quiet (ms) after which the session AUTO-ENDS (glow off, panel kept). Default 5min; agent-tunable. */
34
18
  idleEndMs?: number;
35
- /** Session id, surfaced in the exported run state. */
36
19
  sessionId?: string;
37
- /** Deprecated: accepted for source compat; the live log no longer auto-expires. */
38
20
  narrationDwellMs?: number;
39
- /**
40
- * 'session' (default): base border persists connect→disconnect, busy machine drives only the
41
- * shimmer. 'busy': back-compat - busy machine toggles the base border on/off.
42
- */
43
21
  border?: BorderMode;
44
- /** Max accumulated activity-log rows before the oldest are pruned. Default 50. */
45
22
  logMax?: number;
46
- /** Called when the human clicks pause/resume/end or sends a message from the panel. */
47
23
  onControl?: ControlHandler;
48
- /** Overridable ended-border fade delay (native timer). Default 4000. */
49
24
  endedFadeMs?: number;
50
25
  }
51
26
  export declare const DEFAULT_PACE = 450;
52
- /**
53
- * The pace to actually use: the default in a browser a human is watching, zero in an automated one.
54
- *
55
- * The HUD paces `beforeAct` so a person can see the cursor reach the element before it fires. In a
56
- * headless browser that is 450ms of nothing, charged to the agent, on every action. Measured with
57
- * RETICLE_TRACE across the e2e battery: 42 `act` round-trips, 40 of them in a 452–460ms band -
58
- * a fixed cost, not app work - 19.7 SECONDS in total, 98.5% of all time the battery spent in the
59
- * browser, while every other command ran in 1–4ms.
60
- *
61
- * `navigator.webdriver` is the discriminator because it is exactly the question being asked: true
62
- * under automation (Playwright, CDP, the browser pool's leased tabs, CI), false in the dev browser
63
- * a human has open - the case the HUD exists for, which keeps its pacing untouched.
64
- *
65
- * An EXPLICIT `paceMs` always wins: a recorded demo runs under automation and still wants the glide,
66
- * and an option that quietly ignores what the caller asked for is worse than no option.
67
- */
68
27
  export declare function effectivePaceMs(requested: number | undefined, nav?: Navigator | undefined): number;
69
- /**
70
- * Glow state machine phases (exposed via glowPhase for tests). A burst of activity flips the
71
- * border IN once on the first activity, holds steady (the slow reticle-pulse breathing keeps running
72
- * uninterrupted - no per-action restart/strobe), then fades OUT once after a quiet window.
73
- */
74
28
  export declare const GlowPhase: {
75
29
  readonly IDLE: "idle";
76
30
  readonly BUSY: "busy";
77
31
  readonly FADING: "fading";
78
32
  };
79
33
  export type GlowPhase = (typeof GlowPhase)[keyof typeof GlowPhase];
80
- /** Quiet window before busy -> fading. */
81
34
  export declare const IDLE_AFTER_MS = 700;
82
- /** Liveness heartbeat: how often the act strip refreshes its "idle · {duration}" clock. */
83
35
  export declare const HEARTBEAT_MS = 1000;
84
- /**
85
- * After this much quiet, the act strip stops showing the last action and starts a LIVE, ticking
86
- * "◌ idle · {duration} since last action" - so a watcher can tell a 3s think from a dead agent
87
- * (the killer gap: a frozen panel used to look identical whether the agent paused or stopped).
88
- */
89
36
  export declare const IDLE_NOTICE_MS = 4000;
90
- /** Act-strip copy (presenter-only UI). */
91
37
  export declare const ACT_STRIP: {
92
38
  readonly READY: "Ready";
93
- readonly IDLE_PREFIX: "idle · ";
39
+ readonly PLANNING_PREFIX: "planning next action · ";
40
+ readonly STOPPED: "stopped";
41
+ readonly STOPPED_PREFIX: "stopped · ";
94
42
  readonly NOW: "now";
95
43
  readonly SINCE_LAST: " since last action";
96
44
  };
97
- /** Default session-idle-end: after this much quiet the session auto-ends (glow off, panel persists
98
- * for analysis). Agent-tweakable via reticle_session { idleEndMs } for the app's needs. */
99
45
  export declare const IDLE_END_MS = 300000;
100
- /** Floor for a tweaked idle-end so the agent can't set a uselessly tiny window. */
101
46
  export declare const IDLE_END_MIN_MS = 5000;
102
- /** Must match the glow CSS opacity transition.25s) so phase reaches idle after the fade paints. */
103
47
  export declare const GLOW_FADE_MS = 250;
104
48
  export declare const GLOW_ON = "1";
105
49
  export declare const GLOW_OFF = "0";
106
50
  export declare const DATA_ON = "data-on";
107
- /** The overlay root's state attribute, which the shell styles resolve colour against. */
108
51
  export declare const STATE_ATTR = "data-reticle-state";
109
- /**
110
- * Not a SessionState: there is no session. It is the absence of one, said out loud.
111
- *
112
- * Kept off `SessionState` deliberately — that enum crosses the wire, and this state exists only
113
- * because nothing crossed the wire.
114
- */
115
52
  export declare const UNREACHABLE_STATE = "unreachable";
116
- /** Overlay-root attribute toggled when the HUD is collapsed to the FAB. */
117
53
  export declare const MIN_ATTR = "data-reticle-min";
118
- /** Overlay-root attribute toggled when the agent chat panel is open. */
119
54
  export declare const CHAT_ATTR = "data-reticle-chat";
120
- /** Fixed dock wrapper that stacks chat above the morphing HUD shell. */
121
55
  export declare const DOCK_ATTR = "data-reticle-dock";
122
- /** Collapsed circular control that expands the toolbar. */
123
56
  export declare const FAB_ATTR = "data-reticle-fab";
124
- /** Toolbar chat toggle button. */
125
57
  export declare const CHAT_TOGGLE_ATTR = "data-reticle-chat-toggle";
126
- /** Agent chat panel anchored to the dock. */
127
58
  export declare const CHAT_PANEL_ATTR = "data-reticle-chat-panel";
128
- /** Chat panel opens above or below the HUD bar depending on viewport space. */
129
59
  export declare const CHAT_PLACEMENT_ATTR = "data-reticle-chat-placement";
130
- /** Settings card opens above or below the HUD bar depending on viewport space. */
131
60
  export declare const SETTINGS_PLACEMENT_ATTR = "data-reticle-settings-placement";
132
- /** Horizontal alignment of dock-anchored panels (start = left, end = right). */
133
61
  export declare const DOCK_ALIGN_ATTR = "data-reticle-dock-align";
134
62
  export declare const Placement: {
135
63
  readonly ABOVE: "above";
136
64
  readonly BELOW: "below";
137
65
  };
138
- /** Show/hide annotation markers. */
139
66
  export declare const MARKERS_BTN_ATTR = "data-reticle-markers-btn";
140
- /** Clear every annotation on the page. */
141
67
  export declare const CLEAR_MARKS_ATTR = "data-reticle-clear-marks";
142
- /** Collapsed FAB annotation-count badge. */
143
68
  export declare const MARK_COUNT_ATTR = "data-reticle-mark-count";
144
- /**
145
- * Turn annotation on and off from the toolbar.
146
- *
147
- * Annotation used to be reachable only as a side effect of expanding the HUD, which meant there was
148
- * no way to keep the HUD open and stop annotating, and nothing on screen said the mode existed at
149
- * all. It is a mode the user chooses, so it gets a control they can see and press.
150
- */
151
69
  export declare const ANNOTATE_BTN_ATTR = "data-reticle-annotate-btn";
152
- /** Minimise the agent chat back to the toolbar, without collapsing the whole HUD. */
153
70
  export declare const CHAT_MIN_ATTR = "data-reticle-chat-min";
154
- /** Overlay flag: is the impact report on screen. */
155
71
  export declare const REPORT_ATTR = "data-reticle-report";
156
- /** The report panel itself. */
157
72
  export declare const REPORT_PANEL_ATTR = "data-reticle-report-panel";
158
- /** The report's close button. */
159
73
  export declare const REPORT_CLOSE_ATTR = "data-reticle-report-close";
160
- /** The toolbar button that opens the report. */
161
74
  export declare const REPORT_BTN_ATTR = "data-reticle-report-btn";
162
- /** The capsule that stands in for the chat while it is minimised - state dot + last action. */
163
75
  export declare const CHAT_PILL_ATTR = "data-reticle-chat-pill";
164
- /** Settings gear is open - the card sits above the dock. */
165
76
  export declare const SETTINGS_ATTR = "data-reticle-settings";
166
77
  export declare const SETTINGS_BTN_ATTR = "data-reticle-settings-btn";
167
78
  export declare const SETTINGS_PANEL_ATTR = "data-reticle-settings-panel";
168
79
  export declare const SETTINGS_CLOSE_ATTR = "data-reticle-settings-close";
169
80
  export declare const SETTING_KEY_ATTR = "data-reticle-setting";
170
81
  export declare const SETTINGS_STORAGE_KEY = "reticle-presenter-settings";
171
- /** Accent swatch applied to the dock chrome. */
172
- /** Overlay flag: is the page-edge glow wanted at all (user setting). */
173
82
  export declare const AMBIENT_GLOW_ATTR = "data-reticle-ambient-glow";
174
- /** Overlay mirror of the activity strip's liveness, so CSS can pick the ACTIVE status colour. */
175
83
  export declare const LIVENESS_ATTR = "data-reticle-live";
176
- /** When 1, a transparent blocker captures page pointer events. */
177
84
  export declare const BLOCK_ATTR = "data-reticle-block";
178
- /** When 1, the dock is hidden until the page reloads. */
179
85
  export declare const HIDDEN_UNTIL_RESTART_ATTR = "data-reticle-hidden";
180
- /** When 0, activity-log timestamps are hidden. */
181
86
  export declare const LOG_TIMESTAMPS_ATTR = "data-reticle-log-ts";
182
- /** When 1, the chat panel uses a narrower width. */
183
- /** When 1, HUD motion is reduced for accessibility. */
184
87
  export declare const REDUCE_MOTION_ATTR = "data-reticle-reduce-motion";
185
- /** Docs opened from the settings footer. */
186
88
  export declare const MCP_DOCS_URL: string;
187
- /** HUD has been dragged off the default dock - positioned with explicit left/top. */
188
89
  export declare const HUD_DRAGGED_ATTR = "data-dragged";
189
- /** CSS custom properties written when the HUD is dragged. */
190
90
  export declare const HUD_POS_X_VAR = "--reticle-hud-x";
191
91
  export declare const HUD_POS_Y_VAR = "--reticle-hud-y";
192
- /** Pointer movement below this threshold is treated as a click, not a drag. */
193
92
  export declare const HUD_DRAG_THRESHOLD_PX = 4;
194
- /** Minimum gap between a dragged HUD and the viewport edge. */
195
93
  export declare const HUD_DOCK_MARGIN_PX = 8;
196
- /** Interactive nodes inside the drag handle that must not start a drag (not the FAB itself). */
197
94
  export declare const HUD_DRAG_IGNORE_SEL: string;
198
95
  export declare const THROTTLED_ATTR = "data-reticle-throttled";
96
+ export declare const Z_HUD_TOOLTIP = 100;
97
+ export interface ControlIntent {
98
+ kind: HumanControlKind;
99
+ text?: string;
100
+ }
101
+ export type ControlHandler = (intent: ControlIntent) => void;