@reticlehq/browser 2.2.0 → 2.3.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 (269) hide show
  1. package/dist/actions/actions-dom.d.ts +0 -1
  2. package/dist/actions/actions-dom.js +0 -1
  3. package/dist/actions/actions.d.ts +3 -1
  4. package/dist/actions/actions.js +55 -36
  5. package/dist/actions/scroll.d.ts +0 -1
  6. package/dist/actions/scroll.js +0 -1
  7. package/dist/actions/value-input.d.ts +33 -0
  8. package/dist/actions/value-input.js +63 -0
  9. package/dist/commands/commands.d.ts +0 -1
  10. package/dist/commands/commands.js +15 -7
  11. package/dist/dom/a11y.d.ts +0 -2
  12. package/dist/dom/a11y.js +54 -24
  13. package/dist/dom/auto-anchor.d.ts +0 -1
  14. package/dist/dom/auto-anchor.js +0 -1
  15. package/dist/dom/blind-spots.d.ts +0 -1
  16. package/dist/dom/blind-spots.js +1 -2
  17. package/dist/dom/chart.d.ts +0 -1
  18. package/dist/dom/chart.js +0 -1
  19. package/dist/dom/desktop-capture.d.ts +36 -0
  20. package/dist/dom/desktop-capture.js +113 -0
  21. package/dist/dom/dom-ignore.d.ts +7 -1
  22. package/dist/dom/dom-ignore.js +1 -2
  23. package/dist/dom/occlusion.d.ts +0 -1
  24. package/dist/dom/occlusion.js +0 -1
  25. package/dist/dom/query.d.ts +0 -1
  26. package/dist/dom/query.js +61 -13
  27. package/dist/dom/realm.d.ts +30 -0
  28. package/dist/dom/realm.js +58 -0
  29. package/dist/dom/refs.d.ts +0 -1
  30. package/dist/dom/refs.js +0 -1
  31. package/dist/dom/shadow-registry.d.ts +40 -0
  32. package/dist/dom/shadow-registry.js +165 -0
  33. package/dist/dom/snapshot.d.ts +2 -2
  34. package/dist/dom/snapshot.js +21 -4
  35. package/dist/dom/source.d.ts +0 -1
  36. package/dist/dom/source.js +0 -1
  37. package/dist/dom/theme.d.ts +0 -1
  38. package/dist/dom/theme.js +0 -1
  39. package/dist/dom/virtualized.d.ts +19 -0
  40. package/dist/dom/virtualized.js +80 -0
  41. package/dist/index.d.ts +0 -1
  42. package/dist/index.js +0 -1
  43. package/dist/observers/animation.d.ts +0 -1
  44. package/dist/observers/animation.js +0 -1
  45. package/dist/observers/blind-spots.d.ts +16 -4
  46. package/dist/observers/blind-spots.js +65 -11
  47. package/dist/observers/console.d.ts +0 -1
  48. package/dist/observers/console.js +0 -1
  49. package/dist/observers/dom.d.ts +0 -2
  50. package/dist/observers/dom.js +67 -9
  51. package/dist/observers/download.d.ts +6 -0
  52. package/dist/observers/download.js +103 -0
  53. package/dist/observers/focus.d.ts +0 -1
  54. package/dist/observers/focus.js +0 -1
  55. package/dist/observers/frames.d.ts +12 -0
  56. package/dist/observers/frames.js +67 -0
  57. package/dist/observers/health.d.ts +0 -1
  58. package/dist/observers/health.js +30 -2
  59. package/dist/observers/install-all.d.ts +5 -0
  60. package/dist/observers/install-all.js +63 -0
  61. package/dist/observers/ipc.d.ts +22 -0
  62. package/dist/observers/ipc.js +121 -0
  63. package/dist/observers/network-body.d.ts +17 -1
  64. package/dist/observers/network-body.js +26 -1
  65. package/dist/observers/network-redact.d.ts +0 -1
  66. package/dist/observers/network-redact.js +6 -3
  67. package/dist/observers/network-stream.d.ts +23 -0
  68. package/dist/observers/network-stream.js +102 -0
  69. package/dist/observers/network.d.ts +11 -1
  70. package/dist/observers/network.js +7 -1
  71. package/dist/observers/perf.d.ts +0 -1
  72. package/dist/observers/perf.js +0 -1
  73. package/dist/observers/route.d.ts +0 -1
  74. package/dist/observers/route.js +0 -1
  75. package/dist/observers/scroll.d.ts +0 -1
  76. package/dist/observers/scroll.js +0 -1
  77. package/dist/observers/sdk-failure.d.ts +28 -0
  78. package/dist/observers/sdk-failure.js +60 -0
  79. package/dist/observers/state.d.ts +0 -1
  80. package/dist/observers/state.js +0 -1
  81. package/dist/observers/storage.d.ts +0 -1
  82. package/dist/observers/storage.js +0 -1
  83. package/dist/observers/types.d.ts +0 -1
  84. package/dist/observers/types.js +0 -1
  85. package/dist/patching/capture-method.d.ts +0 -1
  86. package/dist/patching/capture-method.js +0 -1
  87. package/dist/presenter/overlay.d.ts +0 -1
  88. package/dist/presenter/overlay.js +0 -1
  89. package/dist/presenter/presenter-config.d.ts +0 -1
  90. package/dist/presenter/presenter-config.js +0 -1
  91. package/dist/presenter/presenter-controls.d.ts +0 -1
  92. package/dist/presenter/presenter-controls.js +0 -1
  93. package/dist/presenter/presenter-effects.d.ts +0 -1
  94. package/dist/presenter/presenter-effects.js +0 -1
  95. package/dist/presenter/presenter-glow.d.ts +0 -1
  96. package/dist/presenter/presenter-glow.js +0 -1
  97. package/dist/presenter/presenter-log.d.ts +0 -1
  98. package/dist/presenter/presenter-log.js +0 -1
  99. package/dist/presenter/presenter-run-state.d.ts +0 -1
  100. package/dist/presenter/presenter-run-state.js +0 -1
  101. package/dist/presenter/presenter-styles.d.ts +0 -1
  102. package/dist/presenter/presenter-styles.js +0 -1
  103. package/dist/presenter/presenter-tally.d.ts +0 -1
  104. package/dist/presenter/presenter-tally.js +0 -1
  105. package/dist/presenter/presenter-test-helpers.d.ts +0 -1
  106. package/dist/presenter/presenter-test-helpers.js +0 -1
  107. package/dist/presenter/presenter-verbs.d.ts +0 -1
  108. package/dist/presenter/presenter-verbs.js +0 -1
  109. package/dist/presenter/presenter.d.ts +0 -1
  110. package/dist/presenter/presenter.js +0 -1
  111. package/dist/recorder/recorder-styles.d.ts +0 -1
  112. package/dist/recorder/recorder-styles.js +0 -1
  113. package/dist/recorder/recorder.d.ts +0 -1
  114. package/dist/recorder/recorder.js +0 -1
  115. package/dist/registry/adapters.d.ts +0 -1
  116. package/dist/registry/adapters.js +0 -1
  117. package/dist/registry/capabilities.d.ts +0 -1
  118. package/dist/registry/capabilities.js +0 -1
  119. package/dist/registry/commit-and-signal.d.ts +0 -1
  120. package/dist/registry/commit-and-signal.js +0 -1
  121. package/dist/registry/domains.d.ts +0 -1
  122. package/dist/registry/domains.js +0 -1
  123. package/dist/registry/emitter.d.ts +0 -1
  124. package/dist/registry/emitter.js +0 -1
  125. package/dist/registry/store-adapters.d.ts +14 -6
  126. package/dist/registry/store-adapters.js +0 -1
  127. package/dist/registry/stores.d.ts +0 -1
  128. package/dist/registry/stores.js +10 -2
  129. package/dist/reticle-presenter-helpers.d.ts +0 -1
  130. package/dist/reticle-presenter-helpers.js +0 -1
  131. package/dist/reticle.d.ts +3 -2
  132. package/dist/reticle.js +12 -32
  133. package/dist/review/annotator.d.ts +0 -1
  134. package/dist/review/annotator.js +0 -1
  135. package/dist/review/mark-anchor.d.ts +0 -1
  136. package/dist/review/mark-anchor.js +0 -1
  137. package/dist/security/serialization.d.ts +0 -1
  138. package/dist/security/serialization.js +0 -1
  139. package/dist/timers/clock.d.ts +0 -1
  140. package/dist/timers/clock.js +0 -1
  141. package/dist/timers/native-console.d.ts +1 -0
  142. package/dist/timers/native-console.js +9 -0
  143. package/dist/timers/native-timers.d.ts +0 -1
  144. package/dist/timers/native-timers.js +0 -1
  145. package/dist/transport/transport.d.ts +2 -6
  146. package/dist/transport/transport.js +95 -18
  147. package/package.json +8 -3
  148. package/dist/actions/actions-dom.d.ts.map +0 -1
  149. package/dist/actions/actions-dom.js.map +0 -1
  150. package/dist/actions/actions.d.ts.map +0 -1
  151. package/dist/actions/actions.js.map +0 -1
  152. package/dist/actions/scroll.d.ts.map +0 -1
  153. package/dist/actions/scroll.js.map +0 -1
  154. package/dist/commands/commands.d.ts.map +0 -1
  155. package/dist/commands/commands.js.map +0 -1
  156. package/dist/dom/a11y.d.ts.map +0 -1
  157. package/dist/dom/a11y.js.map +0 -1
  158. package/dist/dom/auto-anchor.d.ts.map +0 -1
  159. package/dist/dom/auto-anchor.js.map +0 -1
  160. package/dist/dom/blind-spots.d.ts.map +0 -1
  161. package/dist/dom/blind-spots.js.map +0 -1
  162. package/dist/dom/chart.d.ts.map +0 -1
  163. package/dist/dom/chart.js.map +0 -1
  164. package/dist/dom/dom-ignore.d.ts.map +0 -1
  165. package/dist/dom/dom-ignore.js.map +0 -1
  166. package/dist/dom/occlusion.d.ts.map +0 -1
  167. package/dist/dom/occlusion.js.map +0 -1
  168. package/dist/dom/query.d.ts.map +0 -1
  169. package/dist/dom/query.js.map +0 -1
  170. package/dist/dom/refs.d.ts.map +0 -1
  171. package/dist/dom/refs.js.map +0 -1
  172. package/dist/dom/snapshot.d.ts.map +0 -1
  173. package/dist/dom/snapshot.js.map +0 -1
  174. package/dist/dom/source.d.ts.map +0 -1
  175. package/dist/dom/source.js.map +0 -1
  176. package/dist/dom/theme.d.ts.map +0 -1
  177. package/dist/dom/theme.js.map +0 -1
  178. package/dist/index.d.ts.map +0 -1
  179. package/dist/index.js.map +0 -1
  180. package/dist/observers/animation.d.ts.map +0 -1
  181. package/dist/observers/animation.js.map +0 -1
  182. package/dist/observers/blind-spots.d.ts.map +0 -1
  183. package/dist/observers/blind-spots.js.map +0 -1
  184. package/dist/observers/console.d.ts.map +0 -1
  185. package/dist/observers/console.js.map +0 -1
  186. package/dist/observers/dom.d.ts.map +0 -1
  187. package/dist/observers/dom.js.map +0 -1
  188. package/dist/observers/focus.d.ts.map +0 -1
  189. package/dist/observers/focus.js.map +0 -1
  190. package/dist/observers/health.d.ts.map +0 -1
  191. package/dist/observers/health.js.map +0 -1
  192. package/dist/observers/network-body.d.ts.map +0 -1
  193. package/dist/observers/network-body.js.map +0 -1
  194. package/dist/observers/network-redact.d.ts.map +0 -1
  195. package/dist/observers/network-redact.js.map +0 -1
  196. package/dist/observers/network.d.ts.map +0 -1
  197. package/dist/observers/network.js.map +0 -1
  198. package/dist/observers/perf.d.ts.map +0 -1
  199. package/dist/observers/perf.js.map +0 -1
  200. package/dist/observers/route.d.ts.map +0 -1
  201. package/dist/observers/route.js.map +0 -1
  202. package/dist/observers/scroll.d.ts.map +0 -1
  203. package/dist/observers/scroll.js.map +0 -1
  204. package/dist/observers/state.d.ts.map +0 -1
  205. package/dist/observers/state.js.map +0 -1
  206. package/dist/observers/storage.d.ts.map +0 -1
  207. package/dist/observers/storage.js.map +0 -1
  208. package/dist/observers/types.d.ts.map +0 -1
  209. package/dist/observers/types.js.map +0 -1
  210. package/dist/patching/capture-method.d.ts.map +0 -1
  211. package/dist/patching/capture-method.js.map +0 -1
  212. package/dist/presenter/overlay.d.ts.map +0 -1
  213. package/dist/presenter/overlay.js.map +0 -1
  214. package/dist/presenter/presenter-config.d.ts.map +0 -1
  215. package/dist/presenter/presenter-config.js.map +0 -1
  216. package/dist/presenter/presenter-controls.d.ts.map +0 -1
  217. package/dist/presenter/presenter-controls.js.map +0 -1
  218. package/dist/presenter/presenter-effects.d.ts.map +0 -1
  219. package/dist/presenter/presenter-effects.js.map +0 -1
  220. package/dist/presenter/presenter-glow.d.ts.map +0 -1
  221. package/dist/presenter/presenter-glow.js.map +0 -1
  222. package/dist/presenter/presenter-log.d.ts.map +0 -1
  223. package/dist/presenter/presenter-log.js.map +0 -1
  224. package/dist/presenter/presenter-run-state.d.ts.map +0 -1
  225. package/dist/presenter/presenter-run-state.js.map +0 -1
  226. package/dist/presenter/presenter-styles.d.ts.map +0 -1
  227. package/dist/presenter/presenter-styles.js.map +0 -1
  228. package/dist/presenter/presenter-tally.d.ts.map +0 -1
  229. package/dist/presenter/presenter-tally.js.map +0 -1
  230. package/dist/presenter/presenter-test-helpers.d.ts.map +0 -1
  231. package/dist/presenter/presenter-test-helpers.js.map +0 -1
  232. package/dist/presenter/presenter-verbs.d.ts.map +0 -1
  233. package/dist/presenter/presenter-verbs.js.map +0 -1
  234. package/dist/presenter/presenter.d.ts.map +0 -1
  235. package/dist/presenter/presenter.js.map +0 -1
  236. package/dist/recorder/recorder-styles.d.ts.map +0 -1
  237. package/dist/recorder/recorder-styles.js.map +0 -1
  238. package/dist/recorder/recorder.d.ts.map +0 -1
  239. package/dist/recorder/recorder.js.map +0 -1
  240. package/dist/registry/adapters.d.ts.map +0 -1
  241. package/dist/registry/adapters.js.map +0 -1
  242. package/dist/registry/capabilities.d.ts.map +0 -1
  243. package/dist/registry/capabilities.js.map +0 -1
  244. package/dist/registry/commit-and-signal.d.ts.map +0 -1
  245. package/dist/registry/commit-and-signal.js.map +0 -1
  246. package/dist/registry/domains.d.ts.map +0 -1
  247. package/dist/registry/domains.js.map +0 -1
  248. package/dist/registry/emitter.d.ts.map +0 -1
  249. package/dist/registry/emitter.js.map +0 -1
  250. package/dist/registry/store-adapters.d.ts.map +0 -1
  251. package/dist/registry/store-adapters.js.map +0 -1
  252. package/dist/registry/stores.d.ts.map +0 -1
  253. package/dist/registry/stores.js.map +0 -1
  254. package/dist/reticle-presenter-helpers.d.ts.map +0 -1
  255. package/dist/reticle-presenter-helpers.js.map +0 -1
  256. package/dist/reticle.d.ts.map +0 -1
  257. package/dist/reticle.js.map +0 -1
  258. package/dist/review/annotator.d.ts.map +0 -1
  259. package/dist/review/annotator.js.map +0 -1
  260. package/dist/review/mark-anchor.d.ts.map +0 -1
  261. package/dist/review/mark-anchor.js.map +0 -1
  262. package/dist/security/serialization.d.ts.map +0 -1
  263. package/dist/security/serialization.js.map +0 -1
  264. package/dist/timers/clock.d.ts.map +0 -1
  265. package/dist/timers/clock.js.map +0 -1
  266. package/dist/timers/native-timers.d.ts.map +0 -1
  267. package/dist/timers/native-timers.js.map +0 -1
  268. package/dist/transport/transport.d.ts.map +0 -1
  269. package/dist/transport/transport.js.map +0 -1
@@ -66,4 +66,3 @@ export function installScroll(emit) {
66
66
  io?.disconnect();
67
67
  };
68
68
  }
69
- //# sourceMappingURL=scroll.js.map
@@ -0,0 +1,28 @@
1
+ import type { Emit } from './types.js';
2
+ /**
3
+ * Where in the SDK a failure happened. A fixed vocabulary of OUR module names — never a file path,
4
+ * never anything derived from the user's app — so the field stays low-cardinality and non-identifying
5
+ * while still telling a maintainer which subsystem to open.
6
+ */
7
+ export declare const SdkSite: {
8
+ readonly CONNECT: "connect";
9
+ readonly DOM_OBSERVER: "dom_observer";
10
+ readonly NETWORK_OBSERVER: "network_observer";
11
+ readonly CONSOLE_OBSERVER: "console_observer";
12
+ readonly IPC_OBSERVER: "ipc_observer";
13
+ readonly HEALTH_OBSERVER: "health_observer";
14
+ readonly ROUTER_OBSERVER: "router_observer";
15
+ readonly ANIMATION_OBSERVER: "animation_observer";
16
+ readonly STORE_ADAPTER: "store_adapter";
17
+ readonly SNAPSHOT: "snapshot";
18
+ readonly ACTION: "action";
19
+ readonly COMMAND: "command";
20
+ readonly RECORDER: "recorder";
21
+ readonly TRANSPORT: "transport";
22
+ };
23
+ export type SdkSite = (typeof SdkSite)[keyof typeof SdkSite];
24
+ /**
25
+ * Report that a piece of the SDK failed. Never throws, and never prevents the caller from doing what
26
+ * it was going to do anyway (which is almost always: carry on degraded).
27
+ */
28
+ export declare function reportSdkFailure(emit: Emit, site: SdkSite, error: unknown): void;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The SDK reporting its OWN failures.
3
+ *
4
+ * Half of Reticle runs inside the page, and that half was completely silent. Every `catch` in the SDK
5
+ * swallows by design — correctly, because an instrumentation layer must never break the app it
6
+ * observes — but the consequence was that an observer throwing on page load just produced a quieter
7
+ * product. No error, no signal, no way to know. A user would report "Reticle doesn't see my network
8
+ * calls" and there would be nothing on our side to look at.
9
+ *
10
+ * Two properties make this safe to add:
11
+ *
12
+ * 1. IT MAKES NO NETWORK REQUEST. The report rides the bridge WebSocket the SDK is already connected
13
+ * to — localhost, the same channel every other event uses. The published promise that the SDK
14
+ * talks only to a local bridge stays exactly true, and the daemon decides what (if anything) goes
15
+ * anywhere else. Adding an outbound call from inside someone's app would have been a different
16
+ * product with a different privacy posture.
17
+ * 2. IT CANNOT BREAK THE APP. Reporting is wrapped in its own try/catch and is strictly additive to
18
+ * an existing `catch` block. A failure to report a failure is discarded.
19
+ */
20
+ import { EventType } from '@reticlehq/core';
21
+ /**
22
+ * Where in the SDK a failure happened. A fixed vocabulary of OUR module names — never a file path,
23
+ * never anything derived from the user's app — so the field stays low-cardinality and non-identifying
24
+ * while still telling a maintainer which subsystem to open.
25
+ */
26
+ export const SdkSite = {
27
+ CONNECT: 'connect',
28
+ DOM_OBSERVER: 'dom_observer',
29
+ NETWORK_OBSERVER: 'network_observer',
30
+ CONSOLE_OBSERVER: 'console_observer',
31
+ IPC_OBSERVER: 'ipc_observer',
32
+ HEALTH_OBSERVER: 'health_observer',
33
+ ROUTER_OBSERVER: 'router_observer',
34
+ ANIMATION_OBSERVER: 'animation_observer',
35
+ STORE_ADAPTER: 'store_adapter',
36
+ SNAPSHOT: 'snapshot',
37
+ ACTION: 'action',
38
+ COMMAND: 'command',
39
+ RECORDER: 'recorder',
40
+ TRANSPORT: 'transport',
41
+ };
42
+ /** Cap the message here too — the server strips variables, but an unbounded string is a bad idea twice. */
43
+ const MAX_MESSAGE = 500;
44
+ /**
45
+ * Report that a piece of the SDK failed. Never throws, and never prevents the caller from doing what
46
+ * it was going to do anyway (which is almost always: carry on degraded).
47
+ */
48
+ export function reportSdkFailure(emit, site, error) {
49
+ try {
50
+ const message = error instanceof Error ? error.message : String(error);
51
+ emit(EventType.SDK_FAILED, {
52
+ site,
53
+ message: message.slice(0, MAX_MESSAGE),
54
+ ...(error instanceof Error ? { errorType: error.constructor.name.slice(0, 64) } : {}),
55
+ });
56
+ }
57
+ catch {
58
+ /* a failure report must never become a second failure */
59
+ }
60
+ }
@@ -17,4 +17,3 @@ export declare function diffState(prev: unknown, next: unknown): StateChange[];
17
17
  */
18
18
  export declare function installStoreState(emit: Emit): Teardown;
19
19
  export {};
20
- //# sourceMappingURL=state.d.ts.map
@@ -84,4 +84,3 @@ export function installStoreState(emit) {
84
84
  active.clear();
85
85
  };
86
86
  }
87
- //# sourceMappingURL=state.js.map
@@ -20,4 +20,3 @@ export declare function readStorage(area?: string): StorageSnapshot | Record<str
20
20
  * method access) and re-dispatched via `.call(this)`. Fully reversible; values redacted like the reads.
21
21
  */
22
22
  export declare function installStorage(emit: Emit): Teardown;
23
- //# sourceMappingURL=storage.d.ts.map
@@ -174,4 +174,3 @@ export function installStorage(emit) {
174
174
  proto.clear = origClear;
175
175
  };
176
176
  }
177
- //# sourceMappingURL=storage.js.map
@@ -18,4 +18,3 @@ export type Teardown = () => void;
18
18
  export declare function observeSafely(observation: () => void): void;
19
19
  /** Like observeSafely, but for reading a value the observation needs; undefined if the read throws. */
20
20
  export declare function observeValue<T>(read: () => T): T | undefined;
21
- //# sourceMappingURL=types.d.ts.map
@@ -27,4 +27,3 @@ export function observeValue(read) {
27
27
  return undefined;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=types.js.map
@@ -24,4 +24,3 @@ export declare function captureMethod<T, K extends keyof T>(target: T, key: K):
24
24
  * `set` is an unbound function, and naming that intention once beats disabling the rule at each use.
25
25
  */
26
26
  export declare function captureValueSetter(proto: object): ((this: HTMLElement, value: string) => void) | undefined;
27
- //# sourceMappingURL=capture-method.d.ts.map
@@ -34,4 +34,3 @@ export function captureValueSetter(proto) {
34
34
  const setter = captureMethod(descriptor, 'set');
35
35
  return setter;
36
36
  }
37
- //# sourceMappingURL=capture-method.js.map
@@ -9,4 +9,3 @@ export interface OverlayHandle {
9
9
  /** A tiny in-page status chip: connection + event count. Off by default. */
10
10
  export declare function installOverlay(): OverlayHandle;
11
11
  export {};
12
- //# sourceMappingURL=overlay.d.ts.map
@@ -28,4 +28,3 @@ export function installOverlay() {
28
28
  },
29
29
  };
30
30
  }
31
- //# sourceMappingURL=overlay.js.map
@@ -83,4 +83,3 @@ export declare const DATA_ON = "data-on";
83
83
  /** Overlay-root attribute toggled when the panel is minimised to a bar. */
84
84
  export declare const MIN_ATTR = "data-reticle-min";
85
85
  export declare const THROTTLED_ATTR = "data-reticle-throttled";
86
- //# sourceMappingURL=presenter-config.d.ts.map
@@ -48,4 +48,3 @@ export const DATA_ON = 'data-on';
48
48
  /** Overlay-root attribute toggled when the panel is minimised to a bar. */
49
49
  export const MIN_ATTR = 'data-reticle-min';
50
50
  export const THROTTLED_ATTR = 'data-reticle-throttled';
51
- //# sourceMappingURL=presenter-config.js.map
@@ -71,4 +71,3 @@ export declare class ControlPanel {
71
71
  setState(state: SessionState, text?: string, tone?: PresenterTone): void;
72
72
  }
73
73
  export { DATA_RETICLE_STATE };
74
- //# sourceMappingURL=presenter-controls.d.ts.map
@@ -365,4 +365,3 @@ export class ControlPanel {
365
365
  }
366
366
  }
367
367
  export { DATA_RETICLE_STATE };
368
- //# sourceMappingURL=presenter-controls.js.map
@@ -11,4 +11,3 @@ export declare function ringAround(ring: HTMLElement | undefined, rect: DOMRect)
11
11
  export declare function spawnRipple(root: HTMLElement | undefined, x: number, y: number): void;
12
12
  /** Pace for the human so an action is watchable, not instant. */
13
13
  export declare function pace(ms: number): Promise<void>;
14
- //# sourceMappingURL=presenter-effects.d.ts.map
@@ -37,4 +37,3 @@ export function spawnRipple(root, x, y) {
37
37
  export function pace(ms) {
38
38
  return new Promise((res) => nativeSetTimeout(res, ms));
39
39
  }
40
- //# sourceMappingURL=presenter-effects.js.map
@@ -40,4 +40,3 @@ export declare class GlowController {
40
40
  teardown(): void;
41
41
  }
42
42
  export {};
43
- //# sourceMappingURL=presenter-glow.d.ts.map
@@ -123,4 +123,3 @@ export class GlowController {
123
123
  }, this.#glowFadeMs);
124
124
  }
125
125
  }
126
- //# sourceMappingURL=presenter-glow.js.map
@@ -40,4 +40,3 @@ export declare function formatElapsed(ms: number): string;
40
40
  * Uses createElement/textContent (never innerHTML) so arbitrary narration text can't inject markup.
41
41
  */
42
42
  export declare function appendLogRow(container: HTMLElement, kind: LogKind, text: string, ts: string, logMax: number): LogHandle;
43
- //# sourceMappingURL=presenter-log.d.ts.map
@@ -115,4 +115,3 @@ export function appendLogRow(container, kind, text, ts, logMax) {
115
115
  },
116
116
  };
117
117
  }
118
- //# sourceMappingURL=presenter-log.js.map
@@ -45,4 +45,3 @@ interface RunStateInput {
45
45
  */
46
46
  export declare function buildRunState(input: RunStateInput): PresenterRunState;
47
47
  export {};
48
- //# sourceMappingURL=presenter-run-state.d.ts.map
@@ -34,4 +34,3 @@ export function buildRunState(input) {
34
34
  log: input.runLog.map((e) => ({ ...e })),
35
35
  };
36
36
  }
37
- //# sourceMappingURL=presenter-run-state.js.map
@@ -4,4 +4,3 @@
4
4
  * pure style data (no behavior). LOG_CSS + CONTROLS_CSS are composed in at the end as before.
5
5
  */
6
6
  export declare const PRESENTER_CSS = "\n[data-reticle-glow]{position:fixed;inset:0;pointer-events:none;z-index:2147483600;opacity:0;\n transition:opacity .25s ease;box-shadow:inset 0 0 0 3px rgba(99,102,241,.9),inset 0 0 28px 6px rgba(99,102,241,.45);}\n[data-reticle-glow][data-on=\"1\"]{opacity:1;animation:reticle-pulse 1.6s ease-in-out infinite;}\n[data-reticle-glow][data-on=\"1\"][data-busy=\"1\"]{animation:reticle-shimmer 1.1s ease-in-out infinite;}\n@keyframes reticle-pulse{0%,100%{box-shadow:inset 0 0 0 3px rgba(99,102,241,.9),inset 0 0 22px 4px rgba(99,102,241,.35)}\n 50%{box-shadow:inset 0 0 0 3px rgba(124,127,242,1),inset 0 0 40px 10px rgba(99,102,241,.6)}}\n@keyframes reticle-shimmer{0%,100%{box-shadow:inset 0 0 0 3px rgba(124,127,242,1),inset 0 0 34px 8px rgba(99,102,241,.55)}\n 50%{box-shadow:inset 0 0 0 3px rgba(140,142,255,1),inset 0 0 48px 12px rgba(99,102,241,.7)}}\n[data-reticle-cursor]{position:fixed;top:0;left:0;width:22px;height:22px;margin:-11px 0 0 -11px;\n border:2px solid #6366f1;border-radius:50%;background:rgba(99,102,241,.25);pointer-events:none;\n z-index:2147483646;opacity:0;transition:transform .32s cubic-bezier(.22,1,.36,1),opacity .2s ease;}\n[data-reticle-cursor][data-on=\"1\"]{opacity:1;}\n[data-reticle-cursor]::after{content:\"\";position:absolute;inset:7px;border-radius:50%;background:#6366f1;}\n[data-reticle-ripple]{position:fixed;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;\n background:rgba(99,102,241,.5);pointer-events:none;z-index:2147483645;animation:reticle-ripple .5s ease-out forwards;}\n@keyframes reticle-ripple{from{transform:scale(.4);opacity:.8}to{transform:scale(5);opacity:0}}\n[data-reticle-ring]{position:fixed;pointer-events:none;z-index:2147483644;border:2px solid #22c55e;border-radius:8px;\n box-shadow:0 0 0 3px rgba(34,197,94,.25);opacity:0;transition:opacity .15s ease;}\n[data-reticle-ring][data-on=\"1\"]{opacity:1;}\n[data-reticle-hud]{\n --reticle-accent:#7c83ff;--reticle-accent-soft:rgba(124,131,255,.16);\n --reticle-bg:rgba(13,15,22,.92);--reticle-bg2:rgba(19,22,32,.88);\n --reticle-fg:#e9ebf2;--reticle-muted:#9aa0b2;--reticle-faint:#6a7186;\n --reticle-line:rgba(255,255,255,.09);--reticle-line2:rgba(255,255,255,.05);\n --reticle-read:#54d2e6;--reticle-ok:#3dd7a6;--reticle-bad:#ff7a7a;\n --reticle-font:\"Inter\",system-ui,-apple-system,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;\n --reticle-serif:\"IBM Plex Serif\",Georgia,\"Times New Roman\",serif;\n position:fixed;left:50%;right:auto;bottom:20px;box-sizing:border-box;\n width:384px;height:468px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);\n display:flex;flex-direction:column;overflow:hidden;text-align:left;z-index:2147483647;pointer-events:none;\n font-family:var(--reticle-font);font-size:13px;line-height:1.5;color:var(--reticle-fg);-webkit-font-smoothing:antialiased;\n background:linear-gradient(180deg,var(--reticle-bg),var(--reticle-bg2));\n /* No backdrop-filter here, deliberately. blur(24px) on this panel was measured as the single most\n expensive thing the whole SDK does: a backdrop blur must re-sample everything behind it whenever\n that content changes, and on a page repainting at 60fps that is continuous full-panel work. On\n the hostile fixture it cost +4.0pp of main thread \u2014 five times the rest of the presenter, and\n more than every observer combined. Removing it took total main-thread time from 2.15s to 1.67s\n over an 8s window. The panel background is ~85% opaque, so the glass effect it bought was\n marginal. If you want it back, add it here and expect to pay that. */\n border:1px solid var(--reticle-line);border-radius:20px;\n box-shadow:0 28px 70px -18px rgba(0,0,0,.66),0 0 0 1px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.07),0 0 54px -22px var(--reticle-accent);\n opacity:0;transform:translateX(-50%) translateY(14px) scale(.985);\n transition:opacity .3s ease,transform .42s cubic-bezier(.16,1,.3,1),height .42s cubic-bezier(.16,1,.3,1),border-radius .42s ease,box-shadow .35s ease;}\n[data-reticle-overlay][data-reticle-state=\"paused\"] [data-reticle-hud]{--reticle-accent:#f6b44c;--reticle-accent-soft:rgba(246,180,76,.16);}\n[data-reticle-overlay][data-reticle-state=\"ended\"] [data-reticle-hud]{--reticle-accent:#3dd7a6;--reticle-accent-soft:rgba(61,215,166,.14);}\n[data-reticle-hud]::before{content:\"\";position:absolute;inset:0;border-radius:inherit;pointer-events:none;\n background:radial-gradient(130% 90% at 50% 0%,var(--reticle-accent-soft),transparent 60%);}\n[data-reticle-hud]>*{position:relative;}\n[data-reticle-hud][data-on=\"1\"]{opacity:1;transform:translateX(-50%) translateY(0) scale(1);}\n/* Click-through: the glassy panel itself never blocks the app \u2014 only its interactive controls\n capture clicks (buttons / inputs), so a human can click straight through the HUD to the page.\n The log auto-scrolls, so it stays click-through too (drag-scroll is traded for click-through). */\n[data-reticle-hud] button,[data-reticle-hud] input,[data-reticle-hud] textarea,\n[data-reticle-hud] select,[data-reticle-hud] [contenteditable]{pointer-events:auto;}\n/* When minimised to a pill, the whole bar is the (single) click target to restore. */\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud][data-on=\"1\"]{pointer-events:auto;}\n[data-reticle-hud] .reticle-hud-head{display:flex;align-items:center;gap:8px;flex:none;\n padding:12px 12px 12px 15px;border-bottom:1px solid var(--reticle-line2);}\n[data-reticle-hud] .reticle-dot{width:9px;height:9px;border-radius:50%;flex:none;background:var(--reticle-accent);\n animation:reticle-breathe 2.6s ease-in-out infinite;}\n@keyframes reticle-breathe{0%,100%{box-shadow:0 0 0 0 var(--reticle-accent),0 0 7px 1px var(--reticle-accent);opacity:.85}\n 50%{box-shadow:0 0 0 4px var(--reticle-accent-soft),0 0 15px 3px var(--reticle-accent);opacity:1}}\n[data-reticle-hud] .reticle-brand{font-family:var(--reticle-serif);font-weight:500;font-size:15px;letter-spacing:.01em;color:var(--reticle-fg);}\n[data-reticle-hud] .reticle-head-sp{flex:1;}\n[data-reticle-hud] .reticle-live{display:none;flex:1;min-width:0;color:var(--reticle-muted);font-size:12.5px;\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n[data-reticle-hud] .reticle-maxhint{display:none;flex:none;color:var(--reticle-faint);font-size:13px;line-height:1;}\n[data-reticle-hud] .reticle-act-strip{flex:none;padding:7px 15px;border-bottom:1px solid var(--reticle-line2);background:rgba(0,0,0,.14);}\n[data-reticle-hud] .reticle-act{display:block;color:var(--reticle-muted);font-size:11.5px;\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n[data-reticle-hud] [data-reticle-min-btn]{flex:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;\n width:26px;height:26px;border-radius:8px;border:1px solid var(--reticle-line);background:rgba(255,255,255,.04);\n color:var(--reticle-muted);font-size:15px;line-height:1;transition:background .15s,color .15s,transform .1s;}\n[data-reticle-hud] [data-reticle-min-btn]:hover{color:var(--reticle-fg);background:rgba(255,255,255,.08);}\n[data-reticle-hud] [data-reticle-min-btn]:active{transform:scale(.94);}\n[data-reticle-hud] .reticle-pass{color:var(--reticle-ok);}[data-reticle-hud] .reticle-fail{color:var(--reticle-bad);}\n[data-reticle-hud] .reticle-tally{flex:none;display:inline-flex;align-items:center;gap:8px;font-size:11.5px;\n font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:.01em;}\n[data-reticle-hud] .reticle-tally[hidden]{display:none;}\n[data-reticle-hud] .reticle-tally .reticle-t-pass{color:var(--reticle-ok);}\n[data-reticle-hud] .reticle-tally .reticle-t-fail{color:var(--reticle-bad);}\n[data-reticle-hud] .reticle-tally [data-z=\"1\"]{opacity:.4;}\n@keyframes reticle-tally-pop{0%{transform:scale(1)}38%{transform:scale(1.3)}100%{transform:scale(1)}}\n[data-reticle-hud] .reticle-tally [data-bump=\"1\"]{display:inline-block;animation:reticle-tally-pop .36s cubic-bezier(.16,1,.3,1);}\n[data-reticle-hud] .reticle-chip{display:none;flex:none;font-size:9px;font-weight:600;letter-spacing:.08em;\n padding:2px 7px;border-radius:6px;vertical-align:middle;}\n[data-reticle-hud] .reticle-chip[data-mode=\"reading\"]{display:inline-block;color:var(--reticle-read);\n background:rgba(84,210,230,.12);border:1px solid rgba(84,210,230,.32);}\n[data-reticle-hud] .reticle-chip[data-mode=\"acting\"]{display:inline-block;color:var(--reticle-accent);\n background:var(--reticle-accent-soft);border:1px solid var(--reticle-accent);}\n[data-reticle-hud] .reticle-chip[data-mode=\"idle\"]{display:none;}\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud]{height:50px;border-radius:25px;cursor:pointer;}\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-hud-head{border-bottom:none;height:50px;padding:0 12px 0 16px;}\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-brand,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-chip,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-head-sp,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] [data-reticle-min-btn],\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-ctl,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-badge,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-act-strip,\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] [data-reticle-log],\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] [data-reticle-foot],\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-banner{display:none;}\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-live{display:block;}\n[data-reticle-overlay][data-reticle-min=\"1\"] [data-reticle-hud] .reticle-maxhint{display:inline-flex;}\n[data-reticle-mode=\"reading\"] [data-reticle-glow][data-on=\"1\"]{\n box-shadow:inset 0 0 0 3px rgba(34,211,238,.9),inset 0 0 28px 6px rgba(34,211,238,.4);}\n[data-reticle-mode=\"reading\"] [data-reticle-ring]{border-color:#22d3ee;\n box-shadow:0 0 0 3px rgba(34,211,238,.25);}\n[data-reticle-overlay][data-reticle-throttled=\"1\"] [data-reticle-glow][data-on=\"1\"]{\n box-shadow:inset 0 0 0 3px rgba(251,191,36,.9),inset 0 0 28px 6px rgba(251,191,36,.45);}\n[data-reticle-overlay][data-reticle-throttled=\"1\"] [data-reticle-hud]{--reticle-accent:#fbbf24;--reticle-accent-soft:rgba(251,191,36,.16);}\n\n[data-reticle-log]{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;\n gap:7px;padding:12px 14px;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.16) transparent;}\n[data-reticle-log]::-webkit-scrollbar{width:9px;}\n[data-reticle-log]::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:9px;border:2px solid transparent;background-clip:content-box;}\n[data-reticle-log]::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.26);background-clip:content-box;}\n[data-reticle-log-row]{display:flex;align-items:baseline;gap:8px;font-size:12px;line-height:1.45;\n animation:reticle-row-in .26s cubic-bezier(.16,1,.3,1);}\n@keyframes reticle-row-in{from{opacity:0;transform:translateY(5px);}to{opacity:1;transform:none;}}\n[data-reticle-log-ts]{flex:none;color:var(--reticle-faint);font-size:10px;font-variant-numeric:tabular-nums;padding-top:1px;}\n[data-reticle-log] .reticle-log-text{flex:1;min-width:0;color:#d6dae4;overflow-wrap:anywhere;word-break:break-word;}\n[data-reticle-log] .reticle-res{flex:none;font-weight:700;}\n[data-reticle-log-row][data-kind=\"human\"]{align-self:flex-end;max-width:88%;\n background:var(--reticle-accent-soft);border:1px solid var(--reticle-accent);border-radius:13px 13px 4px 13px;padding:6px 11px;}\n[data-reticle-log-row][data-kind=\"human\"] [data-reticle-log-ts]{display:none;}\n[data-reticle-log-row][data-kind=\"human\"] .reticle-log-text{color:var(--reticle-fg);}\n\n\n[data-reticle-hud] .reticle-ctl{pointer-events:auto;cursor:pointer;flex:none;display:inline-flex;align-items:center;justify-content:center;\n height:26px;padding:0 11px;border-radius:8px;border:1px solid var(--reticle-line);background:rgba(255,255,255,.04);\n color:var(--reticle-muted);font-family:var(--reticle-font);font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1;\n transition:background .15s,color .15s,border-color .15s,transform .1s;}\n[data-reticle-hud] .reticle-ctl:hover{color:var(--reticle-fg);background:rgba(255,255,255,.09);}\n[data-reticle-hud] .reticle-ctl:active{transform:scale(.95);}\n[data-reticle-hud] .reticle-ctl:disabled{opacity:.35;cursor:default;}\n[data-reticle-hud] [data-reticle-end]{color:#ff9aa2;border-color:rgba(255,107,107,.22);}\n[data-reticle-hud] [data-reticle-end]:hover{color:#ff7a7a;border-color:rgba(255,107,107,.5);background:rgba(255,107,107,.1);}\n[data-reticle-hud] .reticle-badge{display:none;align-items:center;flex:none;font-weight:600;letter-spacing:.1em;font-size:9px;\n color:var(--reticle-accent);border:1px solid var(--reticle-accent);background:var(--reticle-accent-soft);padding:2px 8px;border-radius:999px;}\n[data-reticle-overlay][data-reticle-state=\"paused\"] [data-reticle-badge]{display:inline-flex;}\n[data-reticle-hud] [data-reticle-foot]{flex:none;padding:10px 12px 12px;border-top:1px solid var(--reticle-line2);background:rgba(0,0,0,.16);}\n[data-reticle-hud] .reticle-composer{display:flex;align-items:flex-end;gap:6px;background:rgba(255,255,255,.05);\n border:1px solid var(--reticle-line);border-radius:14px;padding:5px 6px 5px 14px;transition:border-color .15s,box-shadow .15s;}\n[data-reticle-hud] .reticle-composer:focus-within{border-color:var(--reticle-accent);box-shadow:0 0 0 3px var(--reticle-accent-soft);}\n[data-reticle-hud] .reticle-msg{flex:1;min-width:0;pointer-events:auto;background:transparent;border:none;outline:none;resize:none;\n box-sizing:border-box;color:var(--reticle-fg);font-family:var(--reticle-font);font-size:13px;line-height:18px;\n height:28px;min-height:28px;max-height:96px;padding:5px 0;overflow-y:auto;\n scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent;}\n[data-reticle-hud] .reticle-msg::-webkit-scrollbar{width:9px;}\n[data-reticle-hud] .reticle-msg::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:9px;border:2px solid transparent;background-clip:content-box;}\n[data-reticle-hud] .reticle-msg::placeholder{color:var(--reticle-faint);}\n[data-reticle-hud] .reticle-msg:disabled{opacity:.5;}\n[data-reticle-hud] .reticle-send{flex:none;width:30px;height:30px;padding:0;border-radius:10px;border:none;cursor:pointer;pointer-events:auto;\n background:var(--reticle-accent);color:#0b0d14;display:inline-flex;align-items:center;justify-content:center;transition:filter .15s,transform .1s;}\n[data-reticle-hud] .reticle-send svg{display:block;}\n[data-reticle-hud] .reticle-send:hover{filter:brightness(1.12);}\n[data-reticle-hud] .reticle-send:active{transform:scale(.9);}\n[data-reticle-hud] .reticle-send:disabled{opacity:.4;cursor:default;}\n[data-reticle-hud] .reticle-banner{display:none;flex:none;padding:8px 15px;color:var(--reticle-accent);\n font-size:11.5px;font-weight:500;border-bottom:1px solid var(--reticle-line2);background:var(--reticle-accent-soft);}\n[data-reticle-overlay][data-reticle-state=\"ended\"] [data-reticle-banner]{display:block;}\n/* Export row: hidden during a live session; revealed when ended so the run can be copied/saved. */\n[data-reticle-hud] .reticle-export{display:none;align-items:center;gap:8px;margin-top:9px;}\n[data-reticle-overlay][data-reticle-state=\"ended\"] [data-reticle-hud] .reticle-export{display:flex;}\n[data-reticle-hud] .reticle-export-msg{color:var(--reticle-ok);font-size:11px;opacity:0;transition:opacity .15s;}\n[data-reticle-hud] .reticle-export-msg[data-show=\"1\"]{opacity:1;}\n[data-reticle-overlay][data-reticle-state=\"paused\"] [data-reticle-glow][data-on=\"1\"]{animation:none;\n box-shadow:inset 0 0 0 3px rgba(246,180,76,.9),inset 0 0 30px 6px rgba(246,180,76,.4);}\n[data-reticle-overlay][data-reticle-state=\"ended\"] [data-reticle-glow][data-on=\"1\"]{animation:none;\n box-shadow:inset 0 0 0 2px rgba(61,215,166,.55);}\n/* Handoff tones tell the human the agent's mode at a glance. waiting = calm teal \"your turn\" (no\n alarm); ask = amber \"answer me\" with a pulse; warn = amber \"agent crashed\" with a pulse. Each leads\n the banner with an icon and overrides the calm ended-green accent. */\n[data-reticle-overlay][data-reticle-tone=\"waiting\"] [data-reticle-hud]{--reticle-accent:#38bdf8;--reticle-accent-soft:rgba(56,189,248,.16);}\n[data-reticle-overlay][data-reticle-tone=\"waiting\"] [data-reticle-banner]{font-weight:600;color:#7dd3fc;}\n[data-reticle-overlay][data-reticle-tone=\"waiting\"] [data-reticle-banner]::before{content:\"\\270B \";}\n[data-reticle-overlay][data-reticle-tone=\"waiting\"] [data-reticle-glow][data-on=\"1\"]{animation:none;\n box-shadow:inset 0 0 0 2px rgba(56,189,248,.5);}\n[data-reticle-overlay][data-reticle-tone=\"ask\"] [data-reticle-hud],\n[data-reticle-overlay][data-reticle-tone=\"warn\"] [data-reticle-hud]{--reticle-accent:#fb923c;--reticle-accent-soft:rgba(251,146,60,.18);}\n[data-reticle-overlay][data-reticle-tone=\"ask\"] [data-reticle-banner],\n[data-reticle-overlay][data-reticle-tone=\"warn\"] [data-reticle-banner]{font-weight:600;color:#fdba74;}\n[data-reticle-overlay][data-reticle-tone=\"ask\"] [data-reticle-banner]::before{content:\"\\2753 \";}\n[data-reticle-overlay][data-reticle-tone=\"warn\"] [data-reticle-banner]::before{content:\"\\26A0\\FE0F \";}\n[data-reticle-overlay][data-reticle-tone=\"ask\"] [data-reticle-glow][data-on=\"1\"],\n[data-reticle-overlay][data-reticle-tone=\"warn\"] [data-reticle-glow][data-on=\"1\"]{animation:reticle-warn-pulse 1.5s ease-in-out infinite;\n box-shadow:inset 0 0 0 2px rgba(251,146,60,.7);}\n@keyframes reticle-warn-pulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(251,146,60,.32);}\n 50%{box-shadow:inset 0 0 0 3px rgba(251,146,60,.85),inset 0 0 26px 5px rgba(251,146,60,.34);}}\n/* Replay-a-flow row: the human re-runs a saved flow with no agent. Hidden until flows are pushed.\n Bounded + self-scrolling: it sits between the flex:1 log and the flex:none composer, so without a\n height cap a long flow list would squeeze the log to nothing and push the message input past the\n panel's overflow:hidden clip. flex:none + max-height + overflow-y keep the log and input always\n visible; extra flow chips scroll inside this section instead of growing the panel. */\n[data-reticle-hud] .reticle-flows{display:none;flex:none;flex-wrap:wrap;align-content:flex-start;gap:6px;\n padding:9px 12px;border-top:1px solid var(--reticle-line2);max-height:88px;overflow-y:auto;overscroll-behavior:contain;}\n[data-reticle-hud] .reticle-flows[data-has=\"1\"]{display:flex;}\n[data-reticle-hud] .reticle-flows::-webkit-scrollbar{width:9px;}\n[data-reticle-hud] .reticle-flows::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:9px;border:2px solid transparent;background-clip:content-box;}\n[data-reticle-hud] .reticle-flows-cap{flex:0 0 100%;margin-bottom:1px;color:var(--reticle-faint);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;}\n[data-reticle-hud] .reticle-flow{pointer-events:auto;cursor:pointer;display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 10px;\n border-radius:7px;border:1px solid var(--reticle-line);background:rgba(255,255,255,.04);color:var(--reticle-muted);\n font-family:var(--reticle-font);font-size:11px;font-weight:500;transition:background .15s,color .15s,border-color .15s,transform .1s;}\n[data-reticle-hud] .reticle-flow:hover{color:var(--reticle-fg);background:var(--reticle-accent-soft);border-color:var(--reticle-accent);}\n[data-reticle-hud] .reticle-flow:active{transform:scale(.95);}\n";
7
- //# sourceMappingURL=presenter-styles.d.ts.map
@@ -124,4 +124,3 @@ export const PRESENTER_CSS = `
124
124
  [data-reticle-overlay][data-reticle-throttled="1"] [data-reticle-hud]{--reticle-accent:#fbbf24;--reticle-accent-soft:rgba(251,191,36,.16);}
125
125
  ${LOG_CSS}
126
126
  ${CONTROLS_CSS}`;
127
- //# sourceMappingURL=presenter-styles.js.map
@@ -17,4 +17,3 @@ export declare function countVerdicts(runLog: {
17
17
  export declare function renderTally(el: HTMLElement | undefined, runLog: {
18
18
  result?: LogResult;
19
19
  }[], prev: TallyCounts): TallyCounts;
20
- //# sourceMappingURL=presenter-tally.d.ts.map
@@ -35,4 +35,3 @@ export function renderTally(el, runLog, prev) {
35
35
  `<span class="reticle-t-fail"${dimF}${bumpFail}>✗ ${String(next.fails)}</span>`;
36
36
  return next;
37
37
  }
38
- //# sourceMappingURL=presenter-tally.js.map
@@ -13,4 +13,3 @@ export interface GlowFlips {
13
13
  stop: () => void;
14
14
  }
15
15
  export declare function trackGlowFlips(glow: HTMLElement): GlowFlips;
16
- //# sourceMappingURL=presenter-test-helpers.d.ts.map
@@ -39,4 +39,3 @@ export function trackGlowFlips(glow) {
39
39
  stop: () => obs.disconnect(),
40
40
  };
41
41
  }
42
- //# sourceMappingURL=presenter-test-helpers.js.map
@@ -1,2 +1 @@
1
1
  export declare function actionVerb(action: string): string;
2
- //# sourceMappingURL=presenter-verbs.d.ts.map
@@ -26,4 +26,3 @@ export function actionVerb(action) {
26
26
  return action;
27
27
  }
28
28
  }
29
- //# sourceMappingURL=presenter-verbs.js.map
@@ -84,4 +84,3 @@ export declare class Presenter {
84
84
  /** Fly the cursor to an element, play the action's effect, then pace for the human. */
85
85
  beforeAct(refId: string, action: string, label: string): Promise<void>;
86
86
  }
87
- //# sourceMappingURL=presenter.d.ts.map
@@ -421,4 +421,3 @@ export class Presenter {
421
421
  spawnRipple(this.#root, cx, cy);
422
422
  }
423
423
  }
424
- //# sourceMappingURL=presenter.js.map
@@ -9,4 +9,3 @@ export declare const BTN_CSS: string;
9
9
  export declare const NAME_CSS: string;
10
10
  export declare const STATUS_CSS: string;
11
11
  export declare const MENU_CSS: string;
12
- //# sourceMappingURL=recorder-styles.d.ts.map
@@ -42,4 +42,3 @@ export const NAME_CSS = [
42
42
  ].join(';');
43
43
  export const STATUS_CSS = ['opacity:.75', 'margin-left:4px'].join(';');
44
44
  export const MENU_CSS = ['display:flex', 'gap:6px', 'align-items:center', 'flex-wrap:wrap'].join(';');
45
- //# sourceMappingURL=recorder-styles.js.map
@@ -57,4 +57,3 @@ export declare function compileRecording(name: string, steps: FlowStep[], annota
57
57
  /** Install the floating recorder toolbar. Default off; gated by the host (reticle.ts recorder flag). */
58
58
  export declare function installRecorder(deps: RecorderDeps): RecorderHandle;
59
59
  export {};
60
- //# sourceMappingURL=recorder.d.ts.map
@@ -451,4 +451,3 @@ class Recorder {
451
451
  export function installRecorder(deps) {
452
452
  return new Recorder(deps);
453
453
  }
454
- //# sourceMappingURL=recorder.js.map
@@ -28,4 +28,3 @@ export declare function readComponentState(el: Element): unknown;
28
28
  */
29
29
  export declare function elementHasHoverHandlers(el: Element): boolean;
30
30
  export declare function adapterNames(): string[];
31
- //# sourceMappingURL=adapters.d.ts.map
@@ -44,4 +44,3 @@ export function elementHasHoverHandlers(el) {
44
44
  export function adapterNames() {
45
45
  return adapters.map((a) => a.name);
46
46
  }
47
- //# sourceMappingURL=adapters.js.map
@@ -22,4 +22,3 @@ export declare function registerCapabilities(input: CapabilitiesInput): void;
22
22
  export declare function getCapabilities(): Capabilities;
23
23
  /** Whether the app has advertised any capabilities (used in the HELLO flag). */
24
24
  export declare function hasCapabilities(): boolean;
25
- //# sourceMappingURL=capabilities.d.ts.map
@@ -45,4 +45,3 @@ export function hasCapabilities() {
45
45
  capabilities.stores.length > 0 ||
46
46
  capabilities.flows.length > 0);
47
47
  }
48
- //# sourceMappingURL=capabilities.js.map
@@ -6,4 +6,3 @@
6
6
  */
7
7
  import type { ReticleEmitter } from './emitter.js';
8
8
  export declare function commitAndSignal<T>(emitter: ReticleEmitter, mutate: () => T, name: string, data?: Record<string, unknown>): T;
9
- //# sourceMappingURL=commit-and-signal.d.ts.map
@@ -9,4 +9,3 @@ export function commitAndSignal(emitter, mutate, name, data) {
9
9
  emitter.signal(name, data);
10
10
  return result;
11
11
  }
12
- //# sourceMappingURL=commit-and-signal.js.map
@@ -12,4 +12,3 @@ export interface ReticleDomain {
12
12
  stores?: readonly string[];
13
13
  }
14
14
  export declare function registerReticleDomain(domain: ReticleDomain): void;
15
- //# sourceMappingURL=domains.d.ts.map
@@ -16,4 +16,3 @@ export function registerReticleDomain(domain) {
16
16
  input.stores = [...domain.stores];
17
17
  registerCapabilities(input);
18
18
  }
19
- //# sourceMappingURL=domains.js.map
@@ -25,4 +25,3 @@ export interface CreateReticleEmitterOptions {
25
25
  * made at module load — before `reticle.connect` — starts working the moment Reticle connects.
26
26
  */
27
27
  export declare function createReticleEmitter(options?: CreateReticleEmitterOptions): ReticleEmitter;
28
- //# sourceMappingURL=emitter.d.ts.map
@@ -24,4 +24,3 @@ export function createReticleEmitter(options = {}) {
24
24
  },
25
25
  };
26
26
  }
27
- //# sourceMappingURL=emitter.js.map
@@ -60,10 +60,19 @@ export interface QuerySnapshot {
60
60
  * ```
61
61
  */
62
62
  export declare function tanstackQueryStore(client: QueryClientLike): StoreLike;
63
- /** The minimum of a Jotai vanilla store this adapter touches. */
64
- interface JotaiStoreLike {
65
- get: (atom: object) => unknown;
66
- sub: (atom: object, listener: () => void) => () => void;
63
+ /**
64
+ * The minimum of a Jotai vanilla store this adapter touches, generic in the ATOM type.
65
+ *
66
+ * `atom: object` was rejected by TypeScript for a real store and the reason is contravariance, not
67
+ * pedantry: Jotai's `get` is `<Value>(atom: Atom<Value>) => Value`, and a function that requires an
68
+ * `Atom` cannot stand in for one that accepts any `object`. So `jotaiStore(createStore(), …)` did
69
+ * not compile — the adapter was advertised, shipped, and unusable from TypeScript without a cast,
70
+ * which the shape-matched fake in the sibling test could never reveal because the fake was written
71
+ * to the same belief the adapter was.
72
+ */
73
+ interface JotaiStoreLike<A> {
74
+ get: (atom: A) => unknown;
75
+ sub: (atom: A, listener: () => void) => () => void;
67
76
  }
68
77
  /**
69
78
  * Expose a chosen set of Jotai atoms as one Reticle store.
@@ -76,7 +85,7 @@ interface JotaiStoreLike {
76
85
  * registerStore('app', jotaiStore(getDefaultStore(), { cart: cartAtom, user: userAtom }));
77
86
  * ```
78
87
  */
79
- export declare function jotaiStore(store: JotaiStoreLike, atoms: Record<string, object>): StoreLike;
88
+ export declare function jotaiStore<A>(store: JotaiStoreLike<A>, atoms: Record<string, A>): StoreLike;
80
89
  /** The minimum of an XState actor this adapter touches. */
81
90
  interface ActorLike {
82
91
  getSnapshot: () => unknown;
@@ -125,4 +134,3 @@ export declare function pushStore(initial: unknown): {
125
134
  push: (value: unknown) => void;
126
135
  };
127
136
  export {};
128
- //# sourceMappingURL=store-adapters.d.ts.map
@@ -132,4 +132,3 @@ export function pushStore(initial) {
132
132
  },
133
133
  };
134
134
  }
135
- //# sourceMappingURL=store-adapters.js.map
@@ -48,4 +48,3 @@ export declare function readStoresWithTruncation(only?: string): {
48
48
  stores: Record<string, unknown>;
49
49
  truncation?: Record<string, TruncationReport>;
50
50
  };
51
- //# sourceMappingURL=stores.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { RETICLE_RENDERS_STORE } from '@reticlehq/core';
2
+ import { nativeWarn } from '../timers/native-console.js';
2
3
  import { sanitizeWithReport } from '../security/serialization.js';
3
4
  const globalStore = globalThis;
4
5
  const stores = (globalStore.__reticleStores ??= new Map());
@@ -41,6 +42,14 @@ export function registerStore(name, source, subscribe) {
41
42
  notifyRegistered(name, getter, sub);
42
43
  return;
43
44
  }
45
+ if (typeof source !== 'function') {
46
+ const hasSubscribe = typeof source === 'object' && source !== null && 'subscribe' in source;
47
+ nativeWarn(`[reticle] store "${name}" is neither a getter function nor a {getState, subscribe} store` +
48
+ (hasSubscribe
49
+ ? ` — it has subscribe but no getState. Wrap it with an adapter or add getState.`
50
+ : '.'));
51
+ return;
52
+ }
44
53
  stores.set(name, source);
45
54
  if (subscribe !== undefined) {
46
55
  subscribers.set(name, subscribe);
@@ -136,8 +145,7 @@ function warnSilentStoreOnce(name) {
136
145
  if (RETICLE_OWNED_STORES.has(name) || warnedSilent.has(name))
137
146
  return;
138
147
  warnedSilent.add(name);
139
- console.warn(`[reticle] store "${name}" was registered without a subscribe function. It can be READ, but its ` +
148
+ nativeWarn(`[reticle] store "${name}" was registered without a subscribe function. It can be READ, but its ` +
140
149
  `changes are invisible: no STATE_CHANGE events, no state diffs in causal summaries, and a state ` +
141
150
  `predicate will never see it update. Pass the store object (or a subscribe callback) to fix.`);
142
151
  }
143
- //# sourceMappingURL=stores.js.map
@@ -16,4 +16,3 @@ export declare function modeForCommand(commandName: string): PresenterMode;
16
16
  * element". Falls back to the bare verb when no target is in the args.
17
17
  */
18
18
  export declare function presentStatus(commandName: string, args?: Record<string, unknown>): string;
19
- //# sourceMappingURL=reticle-presenter-helpers.d.ts.map
@@ -78,4 +78,3 @@ function queryTarget(q) {
78
78
  return name !== undefined ? `"${value}" (${name})` : `"${value}"`;
79
79
  return name !== undefined ? `"${name}"` : undefined;
80
80
  }
81
- //# sourceMappingURL=reticle-presenter-helpers.js.map
package/dist/reticle.d.ts CHANGED
@@ -64,7 +64,9 @@ export interface ReticleConnectOptions {
64
64
  * behind `import.meta.env.DEV` so the SDK is dead-code-eliminated from prod bundles entirely.
65
65
  */
66
66
  export declare function shouldBlockProduction(nodeEnv: string | undefined, allowInProduction: boolean): boolean;
67
- export declare function connectionPolicy(pageHostname: string, bridgeUrl: string, allowNonLocalhost: boolean, token: string | undefined): {
67
+ export declare function connectionPolicy(pageHostname: string, bridgeUrl: string, allowNonLocalhost: boolean, token: string | undefined,
68
+ /** The page's protocol. Desktop webviews (file:, app:, tauri:) are local despite a non-loopback host. */
69
+ pageProtocol?: string): {
68
70
  allowed: boolean;
69
71
  reason?: string;
70
72
  };
@@ -134,4 +136,3 @@ export declare class Reticle {
134
136
  endSession(): void;
135
137
  disconnect(): void;
136
138
  }
137
- //# sourceMappingURL=reticle.d.ts.map