@reticlehq/browser 2.8.0 → 2.10.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 (79) hide show
  1. package/NOTICE +7 -0
  2. package/dist/actions/actions-dom.js +23 -15
  3. package/dist/actions/actions.d.ts +17 -0
  4. package/dist/actions/actions.js +132 -29
  5. package/dist/actions/synthetic-input.d.ts +9 -0
  6. package/dist/actions/synthetic-input.js +40 -0
  7. package/dist/commands/commands.js +11 -1
  8. package/dist/connect-options.d.ts +9 -9
  9. package/dist/dom/a11y.d.ts +9 -0
  10. package/dist/dom/a11y.js +19 -0
  11. package/dist/dom/dom-ignore.d.ts +19 -6
  12. package/dist/dom/dom-ignore.js +20 -13
  13. package/dist/dom/query.d.ts +2 -2
  14. package/dist/dom/query.js +85 -45
  15. package/dist/dom/snapshot.d.ts +5 -0
  16. package/dist/dom/snapshot.js +34 -0
  17. package/dist/dom/source.d.ts +14 -0
  18. package/dist/dom/source.js +16 -0
  19. package/dist/observers/install-all.js +4 -1
  20. package/dist/observers/ipc.d.ts +16 -0
  21. package/dist/observers/ipc.js +19 -1
  22. package/dist/observers/network.d.ts +8 -0
  23. package/dist/observers/network.js +24 -3
  24. package/dist/observers/state.js +21 -2
  25. package/dist/presenter/presenter-brand.d.ts +24 -7
  26. package/dist/presenter/presenter-brand.js +23 -6
  27. package/dist/presenter/presenter-config.d.ts +102 -9
  28. package/dist/presenter/presenter-config.js +94 -8
  29. package/dist/presenter/presenter-controls.d.ts +10 -10
  30. package/dist/presenter/presenter-controls.js +175 -85
  31. package/dist/presenter/presenter-dock-layout.d.ts +6 -0
  32. package/dist/presenter/presenter-dock-layout.js +170 -0
  33. package/dist/presenter/presenter-drag.d.ts +48 -0
  34. package/dist/presenter/presenter-drag.js +198 -0
  35. package/dist/presenter/presenter-effects.d.ts +1 -1
  36. package/dist/presenter/presenter-effects.js +1 -1
  37. package/dist/presenter/presenter-glow.d.ts +5 -5
  38. package/dist/presenter/presenter-glow.js +7 -7
  39. package/dist/presenter/presenter-heroicons-data.d.ts +41 -0
  40. package/dist/presenter/presenter-heroicons-data.js +38 -0
  41. package/dist/presenter/presenter-hud-chrome.d.ts +17 -0
  42. package/dist/presenter/presenter-hud-chrome.js +41 -0
  43. package/dist/presenter/presenter-icons.d.ts +44 -0
  44. package/dist/presenter/presenter-icons.js +100 -0
  45. package/dist/presenter/presenter-log.d.ts +27 -5
  46. package/dist/presenter/presenter-log.js +114 -28
  47. package/dist/presenter/presenter-report-copy.d.ts +83 -0
  48. package/dist/presenter/presenter-report-copy.js +127 -0
  49. package/dist/presenter/presenter-report-styles.d.ts +7 -0
  50. package/dist/presenter/presenter-report-styles.js +102 -0
  51. package/dist/presenter/presenter-report.d.ts +23 -0
  52. package/dist/presenter/presenter-report.js +217 -0
  53. package/dist/presenter/presenter-run-state.d.ts +1 -1
  54. package/dist/presenter/presenter-settings-styles.d.ts +2 -0
  55. package/dist/presenter/presenter-settings-styles.js +153 -0
  56. package/dist/presenter/presenter-settings.d.ts +82 -0
  57. package/dist/presenter/presenter-settings.js +494 -0
  58. package/dist/presenter/presenter-shell-styles.d.ts +1 -0
  59. package/dist/presenter/presenter-shell-styles.js +375 -0
  60. package/dist/presenter/presenter-shell.d.ts +48 -0
  61. package/dist/presenter/presenter-shell.js +408 -0
  62. package/dist/presenter/presenter-styles.d.ts +9 -4
  63. package/dist/presenter/presenter-styles.js +61 -125
  64. package/dist/presenter/presenter-tally.d.ts +8 -11
  65. package/dist/presenter/presenter-tally.js +48 -23
  66. package/dist/presenter/presenter-test-helpers.d.ts +1 -1
  67. package/dist/presenter/presenter-test-helpers.js +1 -1
  68. package/dist/presenter/presenter-verbs.js +2 -2
  69. package/dist/presenter/presenter-workspace.d.ts +15 -0
  70. package/dist/presenter/presenter-workspace.js +180 -0
  71. package/dist/presenter/presenter.d.ts +15 -10
  72. package/dist/presenter/presenter.js +194 -46
  73. package/dist/reticle.d.ts +2 -2
  74. package/dist/reticle.js +23 -19
  75. package/dist/review/annotator-styles.d.ts +6 -0
  76. package/dist/review/annotator-styles.js +81 -0
  77. package/dist/review/annotator.d.ts +29 -17
  78. package/dist/review/annotator.js +477 -146
  79. package/package.json +7 -4
@@ -0,0 +1,81 @@
1
+ import { Z_OVERLAY } from '../presenter/presenter-styles.js';
2
+ /** Markup + CSS for the in-page annotation HUD (markers, hover box, composer). */
3
+ const MARK_ATTR = 'data-reticle-mark';
4
+ const sel = (role) => `[${MARK_ATTR}="${role}"]`;
5
+ export const MARK_PLACEHOLDER = 'What should change?';
6
+ export const MARK_SUBMIT = 'Add';
7
+ export const MARK_CANCEL = 'Cancel';
8
+ export const MARK_PENDING_GLYPH = '+';
9
+ /**
10
+ * ABOVE the presenter overlay, because the overlay contains the page blocker annotate mode raises.
11
+ * One below it, the shield painted over the composer: every click on Cancel or Add landed on the
12
+ * blocker instead of the button, so the note could be neither saved nor dismissed. The root here is
13
+ * pointer-events:none, so only the marks and the composer sit above the HUD - not a new shield.
14
+ */
15
+ const Z_MARK = Z_OVERLAY + 1;
16
+ export const ANNOTATOR_CSS = `
17
+ ${sel('root')}{position:fixed;inset:0;pointer-events:none;z-index:${String(Z_MARK)};}
18
+ ${sel('root')}[data-hide="1"] ${sel('pin')}{display:none;}
19
+ html[data-reticle-mark-active] *{cursor:crosshair !important;}
20
+ html[data-reticle-mark-active] [data-reticle-overlay],
21
+ html[data-reticle-mark-active] [data-reticle-overlay] *,
22
+ html[data-reticle-mark-active] ${sel('pop')},
23
+ html[data-reticle-mark-active] ${sel('pop')} *,
24
+ html[data-reticle-mark-active] ${sel('pin')},
25
+ html[data-reticle-mark-active] ${sel('pending')}{cursor:pointer !important;}
26
+ ${sel('hi')}{position:fixed;pointer-events:none;opacity:0;box-sizing:border-box;
27
+ border:2px solid color-mix(in srgb, var(--reticle-mark-accent, #0088ff) 50%, transparent);
28
+ border-radius:4px;background:color-mix(in srgb, var(--reticle-mark-accent, #0088ff) 4%, transparent);}
29
+ ${sel('hi')}[data-on="1"]{opacity:1;animation:reticle-mark-hi-in .12s ease-out;}
30
+ ${sel('hilabel')}{position:absolute;top:-28px;left:0;font:500 11px/1.2 system-ui,sans-serif;color:#fff;
31
+ background:rgba(0,0,0,.85);padding:.35rem .6rem;border-radius:.375rem;white-space:nowrap;
32
+ max-width:280px;overflow:hidden;text-overflow:ellipsis;pointer-events:none;}
33
+ ${sel('sel')}{position:fixed;pointer-events:none;box-sizing:border-box;border-radius:4px;
34
+ border:2px solid color-mix(in srgb, var(--reticle-mark-accent, #0088ff) 60%, transparent);
35
+ background:color-mix(in srgb, var(--reticle-mark-accent, #0088ff) 5%, transparent);}
36
+ ${sel('pin')},${sel('pending')}{position:fixed;pointer-events:auto;width:22px;height:22px;
37
+ margin:0;border:none;border-radius:50%;background:var(--reticle-mark-accent, #0088ff);color:#fff;
38
+ font:600 11px/22px system-ui,sans-serif;text-align:center;cursor:pointer;
39
+ box-shadow:0 2px 6px rgba(0,0,0,.2),inset 0 0 0 1px rgba(0,0,0,.04);
40
+ transform:translate(-50%,-50%);user-select:none;z-index:1;}
41
+ ${sel('pin')}:hover{transform:translate(-50%,-50%) scale(1.1);z-index:2;}
42
+ ${sel('pin')}[data-stale="1"]{opacity:.45;}
43
+ ${sel('pending')}{cursor:default;}
44
+ ${sel('tip')}{position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%) scale(.909);
45
+ background:#1a1a1a;color:#fff;padding:8px 12px;border-radius:12px;min-width:120px;max-width:200px;
46
+ box-shadow:0 4px 20px rgba(0,0,0,.3),0 0 0 1px rgba(255,255,255,.08);pointer-events:none;text-align:left;
47
+ font:400 13px/1.4 system-ui,sans-serif;display:none;z-index:3;}
48
+ ${sel('pin')}:hover ${sel('tip')}{display:block;}
49
+ ${sel('tipq')}{display:block;font-size:12px;font-style:italic;color:rgba(255,255,255,.6);
50
+ margin-bottom:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
51
+ ${sel('tipn')}{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
52
+ ${sel('pop')}{position:fixed;pointer-events:auto;width:280px;box-sizing:border-box;padding:12px 16px 14px;
53
+ background:#1a1a1a;border-radius:16px;color:#fff;z-index:${String(Z_MARK + 8)};
54
+ box-shadow:0 4px 24px rgba(0,0,0,.3),0 0 0 1px rgba(255,255,255,.08);
55
+ font:13px/1.45 system-ui,-apple-system,"Segoe UI",sans-serif;transform:translateX(-50%);opacity:0;}
56
+ ${sel('pop')}[data-in="1"]{opacity:1;animation:reticle-mark-pop-in .2s cubic-bezier(.34,1.56,.64,1) forwards;}
57
+ ${sel('pop')}.reticle-mark-shake{animation:reticle-mark-shake .25s ease-out;}
58
+ ${sel('pop')} .reticle-mark-where{font-size:12px;font-weight:400;color:rgba(255,255,255,.5);
59
+ margin-bottom:9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
60
+ ${sel('pop')} textarea{box-sizing:border-box;width:100%;min-height:52px;resize:none;padding:8px 10px;
61
+ font:13px/1.45 inherit;background:rgba(255,255,255,.05);color:#fff;
62
+ border:1px solid rgba(255,255,255,.15);border-radius:8px;outline:none;}
63
+ ${sel('pop')} textarea:focus{border-color:var(--reticle-mark-accent, #0088ff);}
64
+ ${sel('pop')} textarea::placeholder{color:rgba(255,255,255,.35);}
65
+ ${sel('pop')} .reticle-mark-row{display:flex;justify-content:flex-end;gap:6px;margin-top:8px;}
66
+ ${sel('pop')} button{font:500 12px/1 system-ui,sans-serif;padding:.4rem .875rem;border-radius:1rem;
67
+ border:none;cursor:pointer;background:transparent;color:rgba(255,255,255,.5);}
68
+ ${sel('pop')} button:hover{background:rgba(255,255,255,.1);color:rgba(255,255,255,.8);}
69
+ ${sel('pop')} button[data-send]{background:var(--reticle-mark-accent, #0088ff);color:#fff;}
70
+ ${sel('pop')} button[data-send]:disabled{opacity:.4;cursor:not-allowed;}
71
+ @keyframes reticle-mark-hi-in{from{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}
72
+ @keyframes reticle-mark-pop-in{from{opacity:0;transform:translateX(-50%) scale(.95) translateY(4px)}
73
+ to{opacity:1;transform:translateX(-50%) scale(1) translateY(0)}}
74
+ @keyframes reticle-mark-shake{
75
+ 0%,100%{transform:translateX(-50%)}
76
+ 20%{transform:translateX(calc(-50% - 3px))}
77
+ 40%{transform:translateX(calc(-50% + 3px))}
78
+ 60%{transform:translateX(calc(-50% - 2px))}
79
+ 80%{transform:translateX(calc(-50% + 2px))}}
80
+ `;
81
+ export const ANNOTATOR_ROOT_HTML = `<div ${MARK_ATTR}="hi"><span ${MARK_ATTR}="hilabel"></span></div><div ${MARK_ATTR}="sel" hidden></div>`;
@@ -1,35 +1,47 @@
1
1
  import { EventType } from '@reticlehq/core';
2
2
  /**
3
- * The human "annotate the bug where you see it" surface. A dev toggles annotate mode, clicks the
4
- * element that looks wrong, types what's wrong, and Reticle pins a numbered marker + emits a HUMAN_MARK
5
- * event the agent drains (reticle_review). The mark carries the element's re-resolvable anchor and —
6
- * when available — the source file:line, so the agent fixes the exact element/code, not a guess.
3
+ * What the HUD is told about a mark the moment it is placed.
7
4
  *
8
- * Self-contained and dev-only: every node carries a `data-reticle-mark` attribute so Reticle's own
9
- * observers ignore it (see dom-ignore.ts), and clicks on its own UI never become marks.
5
+ * The row used to get the note and the anchor's label - "generic: my feedback" - which names
6
+ * neither the element nor which of several marks it is. The pin on the page is numbered, so the
7
+ * row carries the same number, plus the source the anchor already resolved.
10
8
  */
11
- /** Injected so the SDK wires the real emit/clock and tests can drive both. */
9
+ export interface MarkReport {
10
+ note: string;
11
+ /** The anchor the agent will look the element up by, e.g. `[data-testid="deploy-submit"]`. */
12
+ anchor: string;
13
+ label: string;
14
+ /** 1-based, matching the number drawn in the pin. */
15
+ index: number;
16
+ /** file:line, when the app is source-stamped. */
17
+ source?: string;
18
+ }
12
19
  export interface AnnotatorDeps {
13
20
  emit: (type: EventType, data: Record<string, unknown>) => void;
14
21
  now: () => number;
15
- /**
16
- * Optional: called after a mark is sent so the SDK can echo it into the live presenter panel — the
17
- * human sees their flag land in the same activity log they watch the agent in. No-op when the
18
- * presenter isn't mounted.
19
- */
20
- onMark?: (note: string, label: string) => void;
22
+ onMark?: (mark: MarkReport) => void;
23
+ shouldBlock?: () => boolean;
24
+ onCountChange?: (count: number) => void;
25
+ }
26
+ export interface AnnotatorChrome {
27
+ markersBtn?: HTMLElement;
28
+ clearBtn?: HTMLElement;
29
+ countEl?: HTMLElement;
21
30
  }
22
31
  export declare class Annotator {
23
32
  #private;
24
33
  constructor(deps: AnnotatorDeps);
25
- /** Whether annotate mode is currently capturing clicks. */
26
34
  get active(): boolean;
27
- /** Number of marks sent this session (drives the pin numbering). */
28
35
  get markCount(): number;
29
36
  mount(): void;
37
+ /** Drive marker/highlight chrome from the HUD accent swatch. */
38
+ setAccent(hex: string): void;
39
+ /** @deprecated HUD expand/collapse owns annotate mode; chrome buttons are hide/clear. */
40
+ attachFlagButton(btn: HTMLElement): void;
41
+ attachChrome(chrome: AnnotatorChrome): void;
30
42
  destroy(): void;
31
- /** Turn annotate mode on/off. With no argument, flips the current state. */
32
43
  toggle(on?: boolean): void;
44
+ clearAll(): void;
45
+ syncAnchors(): void;
33
46
  }
34
- /** Construct + mount the annotator (mirrors installRecorder's ergonomics). */
35
47
  export declare function installAnnotator(deps: AnnotatorDeps): Annotator;