@reticlehq/browser 2.13.1 → 2.14.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.
- package/dist/actions/actions-dom.d.ts +0 -20
- package/dist/actions/actions-dom.js +0 -66
- package/dist/actions/actions-press.d.ts +10 -0
- package/dist/actions/actions-press.js +77 -0
- package/dist/actions/actions.d.ts +0 -89
- package/dist/actions/actions.js +24 -358
- package/dist/actions/appeared-text.d.ts +0 -20
- package/dist/actions/appeared-text.js +0 -36
- package/dist/actions/danger-context.d.ts +3 -0
- package/dist/actions/danger-context.js +39 -0
- package/dist/actions/scroll.d.ts +0 -9
- package/dist/actions/scroll.js +0 -7
- package/dist/actions/synthetic-input.d.ts +0 -7
- package/dist/actions/synthetic-input.js +0 -27
- package/dist/actions/value-input.d.ts +0 -30
- package/dist/actions/value-input.js +0 -33
- package/dist/commands/commands.d.ts +0 -2
- package/dist/commands/commands.js +0 -67
- package/dist/connect-options.d.ts +2 -96
- package/dist/dom/a11y.d.ts +0 -29
- package/dist/dom/a11y.js +1 -88
- package/dist/dom/auto-anchor.d.ts +0 -40
- package/dist/dom/auto-anchor.js +0 -33
- package/dist/dom/chart.d.ts +0 -61
- package/dist/dom/chart.js +0 -60
- package/dist/dom/desktop-capture.d.ts +0 -30
- package/dist/dom/desktop-capture.js +0 -72
- package/dist/dom/dom-ignore.d.ts +0 -30
- package/dist/dom/dom-ignore.js +0 -47
- package/dist/dom/occlusion.d.ts +0 -7
- package/dist/dom/occlusion.js +0 -7
- package/dist/dom/query.d.ts +0 -14
- package/dist/dom/query.js +48 -214
- package/dist/dom/realm.d.ts +0 -20
- package/dist/dom/realm.js +0 -28
- package/dist/dom/refs.d.ts +0 -76
- package/dist/dom/refs.js +2 -133
- package/dist/dom/shadow-registry.d.ts +0 -33
- package/dist/dom/shadow-registry.js +2 -72
- package/dist/dom/snapshot.d.ts +2 -43
- package/dist/dom/snapshot.js +26 -151
- package/dist/dom/source.d.ts +0 -44
- package/dist/dom/source.js +0 -45
- package/dist/dom/theme.d.ts +0 -37
- package/dist/dom/theme.js +2 -52
- package/dist/dom/virtualized.d.ts +0 -17
- package/dist/dom/virtualized.js +0 -27
- package/dist/edit-epoch.d.ts +0 -22
- package/dist/edit-epoch.js +0 -52
- package/dist/index.js +1 -23
- package/dist/observers/animation.d.ts +0 -1
- package/dist/observers/animation.js +0 -3
- package/dist/observers/blind-spots.d.ts +0 -26
- package/dist/observers/blind-spots.js +2 -61
- package/dist/observers/console.d.ts +1 -2
- package/dist/observers/console.js +41 -30
- package/dist/observers/context-open.d.ts +1 -11
- package/dist/observers/context-open.js +10 -14
- package/dist/observers/departure.d.ts +3 -0
- package/dist/observers/departure.js +52 -0
- package/dist/observers/dialogs.d.ts +2 -0
- package/dist/observers/dialogs.js +39 -0
- package/dist/observers/dom.js +0 -44
- package/dist/observers/download.d.ts +1 -2
- package/dist/observers/download.js +38 -55
- package/dist/observers/focus.d.ts +0 -6
- package/dist/observers/focus.js +0 -7
- package/dist/observers/frames.d.ts +0 -9
- package/dist/observers/frames.js +1 -28
- package/dist/observers/health.d.ts +0 -5
- package/dist/observers/health.js +1 -33
- package/dist/observers/install-all.d.ts +2 -0
- package/dist/observers/install-all.js +26 -27
- package/dist/observers/ipc.d.ts +0 -25
- package/dist/observers/ipc.js +0 -65
- package/dist/observers/navigation.d.ts +2 -0
- package/dist/observers/navigation.js +33 -0
- package/dist/observers/network-body.d.ts +5 -28
- package/dist/observers/network-body.js +11 -108
- package/dist/observers/network-redact.d.ts +1 -20
- package/dist/observers/network-redact.js +1 -80
- package/dist/observers/network-stream.d.ts +0 -21
- package/dist/observers/network-stream.js +1 -44
- package/dist/observers/network.d.ts +2 -26
- package/dist/observers/network.js +177 -294
- package/dist/observers/perf.d.ts +0 -10
- package/dist/observers/perf.js +0 -16
- package/dist/observers/route.d.ts +1 -2
- package/dist/observers/route.js +13 -19
- package/dist/observers/scroll.d.ts +0 -1
- package/dist/observers/scroll.js +0 -9
- package/dist/observers/sdk-failure.d.ts +1 -9
- package/dist/observers/sdk-failure.js +1 -30
- package/dist/observers/state.d.ts +1 -11
- package/dist/observers/state.js +13 -41
- package/dist/observers/storage.d.ts +0 -14
- package/dist/observers/storage.js +10 -34
- package/dist/observers/types.d.ts +0 -15
- package/dist/observers/types.js +0 -14
- package/dist/patching/capture-method.d.ts +0 -24
- package/dist/patching/capture-method.js +0 -26
- package/dist/presenter/overlay.d.ts +0 -1
- package/dist/presenter/overlay.js +0 -1
- package/dist/presenter/presenter-brand.d.ts +0 -19
- package/dist/presenter/presenter-brand.js +0 -21
- package/dist/presenter/presenter-config.d.ts +1 -105
- package/dist/presenter/presenter-config.js +2 -91
- package/dist/presenter/presenter-controls.d.ts +0 -29
- package/dist/presenter/presenter-controls.js +3 -131
- package/dist/presenter/presenter-dock-layout.d.ts +0 -3
- package/dist/presenter/presenter-dock-layout.js +0 -4
- package/dist/presenter/presenter-drag.d.ts +2 -24
- package/dist/presenter/presenter-drag.js +0 -26
- package/dist/presenter/presenter-effects.d.ts +0 -9
- package/dist/presenter/presenter-effects.js +0 -9
- package/dist/presenter/presenter-glow.d.ts +0 -21
- package/dist/presenter/presenter-glow.js +1 -27
- package/dist/presenter/presenter-heroicons-data.d.ts +0 -8
- package/dist/presenter/presenter-heroicons-data.js +0 -8
- package/dist/presenter/presenter-hud-chrome.d.ts +0 -10
- package/dist/presenter/presenter-hud-chrome.js +0 -10
- package/dist/presenter/presenter-icons.d.ts +0 -6
- package/dist/presenter/presenter-icons.js +0 -6
- package/dist/presenter/presenter-log.d.ts +0 -38
- package/dist/presenter/presenter-log.js +1 -45
- package/dist/presenter/presenter-report-copy.d.ts +5 -66
- package/dist/presenter/presenter-report-copy.js +5 -66
- package/dist/presenter/presenter-report-styles.d.ts +0 -6
- package/dist/presenter/presenter-report-styles.js +6 -6
- package/dist/presenter/presenter-report.d.ts +4 -7
- package/dist/presenter/presenter-report.js +18 -76
- package/dist/presenter/presenter-run-state.d.ts +0 -7
- package/dist/presenter/presenter-run-state.js +0 -5
- package/dist/presenter/presenter-settings-styles.d.ts +0 -1
- package/dist/presenter/presenter-settings-styles.js +0 -1
- package/dist/presenter/presenter-settings.d.ts +1 -23
- package/dist/presenter/presenter-settings.js +1 -31
- package/dist/presenter/presenter-shell-styles.js +2 -5
- package/dist/presenter/presenter-shell.d.ts +2 -18
- package/dist/presenter/presenter-shell.js +1 -73
- package/dist/presenter/presenter-styles.d.ts +0 -9
- package/dist/presenter/presenter-styles.js +0 -9
- package/dist/presenter/presenter-tally.d.ts +0 -5
- package/dist/presenter/presenter-tally.js +0 -4
- package/dist/presenter/presenter-test-helpers.d.ts +0 -2
- package/dist/presenter/presenter-test-helpers.js +0 -2
- package/dist/presenter/presenter-verbs.js +0 -7
- package/dist/presenter/presenter-workspace.d.ts +0 -4
- package/dist/presenter/presenter-workspace.js +1 -8
- package/dist/presenter/presenter.d.ts +0 -60
- package/dist/presenter/presenter.js +4 -118
- package/dist/recorder/recorder-styles.d.ts +0 -6
- package/dist/recorder/recorder-styles.js +0 -6
- package/dist/recorder/recorder.d.ts +0 -34
- package/dist/recorder/recorder.js +0 -49
- package/dist/registry/adapters.d.ts +0 -10
- package/dist/registry/adapters.js +0 -10
- package/dist/registry/auto-testids.d.ts +0 -19
- package/dist/registry/auto-testids.js +1 -21
- package/dist/registry/capabilities.d.ts +0 -31
- package/dist/registry/capabilities.js +1 -46
- package/dist/registry/commit-and-signal.d.ts +0 -6
- package/dist/registry/commit-and-signal.js +1 -7
- package/dist/registry/domains.d.ts +0 -8
- package/dist/registry/domains.js +0 -7
- package/dist/registry/emitter.d.ts +0 -14
- package/dist/registry/emitter.js +0 -10
- package/dist/registry/store-adapters.d.ts +0 -186
- package/dist/registry/store-adapters.js +0 -163
- package/dist/registry/stores.d.ts +0 -33
- package/dist/registry/stores.js +0 -59
- package/dist/reticle-presenter-helpers.d.ts +0 -13
- package/dist/reticle-presenter-helpers.js +0 -14
- package/dist/reticle.d.ts +1 -52
- package/dist/reticle.js +20 -145
- package/dist/review/annotator-styles.js +0 -7
- package/dist/review/annotator.d.ts +2 -13
- package/dist/review/annotator.js +0 -40
- package/dist/review/mark-anchor.d.ts +0 -11
- package/dist/review/mark-anchor.js +0 -8
- package/dist/security/serialization.d.ts +0 -20
- package/dist/security/serialization.js +1 -66
- package/dist/session-continuity.d.ts +0 -16
- package/dist/session-continuity.js +1 -20
- package/dist/timers/clock.d.ts +1 -14
- package/dist/timers/clock.js +59 -60
- package/dist/timers/native-console.js +0 -4
- package/dist/timers/native-timers.d.ts +0 -25
- package/dist/timers/native-timers.js +3 -33
- package/dist/transport/transport.d.ts +0 -51
- package/dist/transport/transport.js +3 -129
- package/dist/transport/unreachable-message.d.ts +0 -17
- package/dist/transport/unreachable-message.js +0 -17
- package/dist/util/captured-method.d.ts +0 -35
- package/dist/util/captured-method.js +0 -35
- package/package.json +2 -2
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
import { PresenterReport } from './presenter-report.js';
|
|
2
2
|
import { type SettingsHost } from './presenter-settings.js';
|
|
3
|
-
|
|
3
|
+
interface HudShellCallbacks {
|
|
4
4
|
onChatOpen?: () => void;
|
|
5
5
|
onChatClose?: () => void;
|
|
6
6
|
onExpand?: () => void;
|
|
7
|
-
/** The user pressed the annotate toggle. `on` is the state they asked for. */
|
|
8
7
|
onAnnotateToggle?: (on: boolean) => void;
|
|
9
8
|
onCollapse?: () => void;
|
|
10
9
|
settings?: SettingsHost;
|
|
11
10
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Morphing HUD shell: circular FAB ↔ icon toolbar, plus the agent chat panel above.
|
|
14
|
-
* Expand enters annotation mode; the page stays clickable except for captured annotate clicks.
|
|
15
|
-
*/
|
|
16
11
|
export declare class HudShell {
|
|
17
12
|
#private;
|
|
18
13
|
constructor(callbacks?: HudShellCallbacks);
|
|
19
|
-
/** Markup for the dock wrapper (chat panel + morphing HUD shell). */
|
|
20
14
|
static dockHtml(actStripHtml: string, bannerHtml: string, logAttr: string, flowsHtml: string, footHtml: string): string;
|
|
21
|
-
/** The impact report, so the presenter can feed it and the chat can open it. */
|
|
22
15
|
get report(): PresenterReport;
|
|
23
|
-
/** Does the user currently want to annotate? */
|
|
24
16
|
isAnnotateOn(): boolean;
|
|
25
|
-
/** Set the toggle and reflect it on the button, without firing the callback. */
|
|
26
17
|
setAnnotateOn(on: boolean): void;
|
|
27
18
|
mount(root: HTMLElement): void;
|
|
28
19
|
teardown(): void;
|
|
@@ -33,14 +24,7 @@ export declare class HudShell {
|
|
|
33
24
|
openChat(): void;
|
|
34
25
|
closeChat(): void;
|
|
35
26
|
toggleChat(): void;
|
|
36
|
-
/**
|
|
37
|
-
* The chat, asked for by a PERSON - so it takes the slot from the report.
|
|
38
|
-
*
|
|
39
|
-
* `openChat` is also called by `expand`, which the agent triggers at session start; routing that
|
|
40
|
-
* through here closed the impact report every time the agent touched the app, which is precisely
|
|
41
|
-
* when you are reading it.
|
|
42
|
-
*/
|
|
43
27
|
showChat(): void;
|
|
44
|
-
/** Pulse the FAB when new activity arrives while collapsed. */
|
|
45
28
|
pulseFab(active: boolean): void;
|
|
46
29
|
}
|
|
30
|
+
export {};
|
|
@@ -12,16 +12,10 @@ const DRAG_HANDLE_CLASS = 'reticle-toolbar-drag';
|
|
|
12
12
|
const TRANSITION_LOCK_MS = 120;
|
|
13
13
|
const ANNOTATE_LABEL = 'Annotate';
|
|
14
14
|
const CHAT_MIN_LABEL = 'Minimise chat';
|
|
15
|
-
/** The minimised chat capsule's label - it reopens the panel. */
|
|
16
15
|
const CHAT_PILL_LABEL = 'Open agent chat';
|
|
17
|
-
/** The toolbar entry to the impact report. */
|
|
18
16
|
const REPORT_LABEL = 'Impact';
|
|
19
17
|
const SETTINGS_LABEL = 'Settings';
|
|
20
18
|
const EXIT_LABEL = 'Exit';
|
|
21
|
-
/**
|
|
22
|
-
* Morphing HUD shell: circular FAB ↔ icon toolbar, plus the agent chat panel above.
|
|
23
|
-
* Expand enters annotation mode; the page stays clickable except for captured annotate clicks.
|
|
24
|
-
*/
|
|
25
19
|
export class HudShell {
|
|
26
20
|
#root;
|
|
27
21
|
#dock;
|
|
@@ -35,32 +29,11 @@ export class HudShell {
|
|
|
35
29
|
#transitionLock = false;
|
|
36
30
|
#suppressFabClick = false;
|
|
37
31
|
#annotateBtn;
|
|
38
|
-
/**
|
|
39
|
-
* Whether the USER wants to annotate. Distinct from whether annotation is currently possible,
|
|
40
|
-
* which also needs a live session and an expanded HUD — this is the half the user controls, and
|
|
41
|
-
* conflating the two is why there was no way to keep the HUD open without annotating.
|
|
42
|
-
*
|
|
43
|
-
* OFF until asked for. It began as `true` to preserve the old behaviour where expanding the HUD
|
|
44
|
-
* silently entered annotate mode, and that is exactly what made the toolbar icon look permanently
|
|
45
|
-
* lit: the toolbar is only visible while expanded, so an intent that defaults to on is on every
|
|
46
|
-
* time you can see it. Annotate mode also captures clicks, so defaulting it on means a click lands
|
|
47
|
-
* as a mark before anyone asked for one. It is a mode now, and modes are entered deliberately.
|
|
48
|
-
*/
|
|
49
32
|
#annotateOn = false;
|
|
50
33
|
#toggleSync;
|
|
51
|
-
/**
|
|
52
|
-
* One signal for every listener this shell registers, so teardown cannot drift from mount.
|
|
53
|
-
*
|
|
54
|
-
* The click handlers below are anonymous closures over `this`: there is no reference to hand to
|
|
55
|
-
* `removeEventListener`, so before this they were never removed at all. Mounting twice onto the
|
|
56
|
-
* same root therefore stacked a second set, and every handler kept the shell reachable for as
|
|
57
|
-
* long as its element lived.
|
|
58
|
-
*/
|
|
59
34
|
#listeners;
|
|
60
35
|
#report = new PresenterReport({
|
|
61
36
|
onBeforeOpen: () => {
|
|
62
|
-
// One panel at a time in the slot above the toolbar. The chat, the settings and the report
|
|
63
|
-
// all anchor there, so opening one over another stacks two glass cards and reads as a bug.
|
|
64
37
|
this.#settings.close();
|
|
65
38
|
this.closeChat();
|
|
66
39
|
},
|
|
@@ -71,22 +44,19 @@ export class HudShell {
|
|
|
71
44
|
this.#settings = new PresenterSettingsPanel({
|
|
72
45
|
...callbacks.settings,
|
|
73
46
|
onBeforeOpen: () => {
|
|
74
|
-
// Settings takes the slot from BOTH neighbours. Closing only the chat left the report
|
|
75
|
-
// sitting behind the settings card - two glass panels stacked in one anchor.
|
|
76
47
|
this.closeChat();
|
|
77
48
|
this.#report.close();
|
|
78
49
|
callbacks.settings?.onBeforeOpen?.();
|
|
79
50
|
},
|
|
80
51
|
});
|
|
81
52
|
}
|
|
82
|
-
/** Markup for the dock wrapper (chat panel + morphing HUD shell). */
|
|
83
53
|
static dockHtml(actStripHtml, bannerHtml, logAttr, flowsHtml, footHtml) {
|
|
84
54
|
const annotate = hiToggleIconHtml(PresenterIcon.ANNOTATE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
85
55
|
const chart = hiToggleIconHtml(PresenterIcon.CHART, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
86
56
|
const gear = hiToggleIconHtml(PresenterIcon.GEAR, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
87
57
|
const exit = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
88
58
|
return `<div ${DOCK_ATTR}>
|
|
89
|
-
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="
|
|
59
|
+
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="region" aria-label="Reticle session" aria-hidden="true">
|
|
90
60
|
<div class="reticle-chat-head">
|
|
91
61
|
<span class="reticle-chat-brand">${MARK_SVG}<span class="reticle-chat-brandname">${BRAND_NAME}</span></span>
|
|
92
62
|
</div>
|
|
@@ -134,11 +104,9 @@ export class HudShell {
|
|
|
134
104
|
</div>
|
|
135
105
|
</div>`;
|
|
136
106
|
}
|
|
137
|
-
/** The impact report, so the presenter can feed it and the chat can open it. */
|
|
138
107
|
get report() {
|
|
139
108
|
return this.#report;
|
|
140
109
|
}
|
|
141
|
-
/** Light exactly the toolbar buttons whose panels are open. */
|
|
142
110
|
#syncToolbarToggles() {
|
|
143
111
|
const root = this.#root;
|
|
144
112
|
if (root === undefined)
|
|
@@ -152,11 +120,9 @@ export class HudShell {
|
|
|
152
120
|
lit(SETTINGS_BTN_ATTR, '1' === root.getAttribute(SETTINGS_ATTR));
|
|
153
121
|
lit(REPORT_BTN_ATTR, '1' === root.getAttribute(REPORT_ATTR));
|
|
154
122
|
}
|
|
155
|
-
/** Does the user currently want to annotate? */
|
|
156
123
|
isAnnotateOn() {
|
|
157
124
|
return this.#annotateOn;
|
|
158
125
|
}
|
|
159
|
-
/** Set the toggle and reflect it on the button, without firing the callback. */
|
|
160
126
|
setAnnotateOn(on) {
|
|
161
127
|
this.#annotateOn = on;
|
|
162
128
|
this.#annotateBtn?.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
@@ -200,10 +166,6 @@ export class HudShell {
|
|
|
200
166
|
root.removeAttribute(CHAT_ATTR);
|
|
201
167
|
this.#settings.mount(root);
|
|
202
168
|
this.#report.mount(root);
|
|
203
|
-
// The toolbar's lit state FOLLOWS the panels, rather than being set by whoever was clicked.
|
|
204
|
-
// Set at click time, a button stayed lit after its panel was closed by the panel that replaced
|
|
205
|
-
// it - two icons active, one panel open. The observer is the only place that can be right for
|
|
206
|
-
// every path: the toolbar, Escape, click-outside, and one panel closing another.
|
|
207
169
|
this.#toggleSync = new MutationObserver(() => this.#syncToolbarToggles());
|
|
208
170
|
this.#toggleSync.observe(root, {
|
|
209
171
|
attributes: true,
|
|
@@ -249,13 +211,8 @@ export class HudShell {
|
|
|
249
211
|
document.addEventListener('keydown', this.#onKeyDown, { signal });
|
|
250
212
|
}
|
|
251
213
|
teardown() {
|
|
252
|
-
// One call for all nine registrations. It cannot fall out of step with mount() the way a list
|
|
253
|
-
// of removeEventListener calls can, which is the whole point.
|
|
254
214
|
this.#listeners?.abort();
|
|
255
215
|
this.#listeners = undefined;
|
|
256
|
-
// NOT covered by the signal: a MutationObserver takes no `signal` option. This disconnect was
|
|
257
|
-
// missing entirely, so the observer kept `root` — and through it the shell — alive after
|
|
258
|
-
// teardown, and a re-mount left the previous one still firing.
|
|
259
216
|
this.#toggleSync?.disconnect();
|
|
260
217
|
this.#toggleSync = undefined;
|
|
261
218
|
this.#dragTeardown?.();
|
|
@@ -286,12 +243,6 @@ export class HudShell {
|
|
|
286
243
|
if (this.#fab !== undefined)
|
|
287
244
|
this.#fab.setAttribute('aria-expanded', 'true');
|
|
288
245
|
this.#callbacks.onExpand?.();
|
|
289
|
-
// The chat IS the HUD's content: expanding to a toolbar with nothing above it made the agent's
|
|
290
|
-
// log something you had to know to go looking for. Unconditional on purpose — the way to a bare
|
|
291
|
-
// toolbar is the chat's own minimise button, not a preference. `Auto-open chat` is a different
|
|
292
|
-
// question (should it appear with no click at all, at session start) and stays separate, because
|
|
293
|
-
// wiring expand to it made session start expand the HUD and the FAB never appeared.
|
|
294
|
-
// `openChat` re-enters `expand` only when collapsed, and MIN_ATTR is already cleared above.
|
|
295
246
|
this.openChat();
|
|
296
247
|
if (this.#dock !== undefined)
|
|
297
248
|
scheduleSyncDockLayout(this.#dock, this.#root);
|
|
@@ -316,8 +267,6 @@ export class HudShell {
|
|
|
316
267
|
if (this.isChatOpen())
|
|
317
268
|
return;
|
|
318
269
|
this.#root.setAttribute(CHAT_ATTR, '1');
|
|
319
|
-
// The panel had no layout while it was closed, so its feed could not follow the newest row.
|
|
320
|
-
// Now that it does, put it there before it is looked at.
|
|
321
270
|
const log = this.#root.querySelector('[data-reticle-log]');
|
|
322
271
|
if (log !== null)
|
|
323
272
|
settleLogAtLatest(log);
|
|
@@ -327,10 +276,6 @@ export class HudShell {
|
|
|
327
276
|
this.#callbacks.onChatOpen?.();
|
|
328
277
|
if (this.#dock !== undefined)
|
|
329
278
|
scheduleSyncDockLayout(this.#dock, this.#root);
|
|
330
|
-
const input = this.#root.querySelector('[data-reticle-input]');
|
|
331
|
-
if (input !== null && !input.disabled) {
|
|
332
|
-
requestAnimationFrame(() => input.focus());
|
|
333
|
-
}
|
|
334
279
|
}
|
|
335
280
|
closeChat() {
|
|
336
281
|
if (this.#root === undefined || !this.isChatOpen())
|
|
@@ -349,18 +294,10 @@ export class HudShell {
|
|
|
349
294
|
else
|
|
350
295
|
this.showChat();
|
|
351
296
|
}
|
|
352
|
-
/**
|
|
353
|
-
* The chat, asked for by a PERSON - so it takes the slot from the report.
|
|
354
|
-
*
|
|
355
|
-
* `openChat` is also called by `expand`, which the agent triggers at session start; routing that
|
|
356
|
-
* through here closed the impact report every time the agent touched the app, which is precisely
|
|
357
|
-
* when you are reading it.
|
|
358
|
-
*/
|
|
359
297
|
showChat() {
|
|
360
298
|
this.#report.close();
|
|
361
299
|
this.openChat();
|
|
362
300
|
}
|
|
363
|
-
/** Pulse the FAB when new activity arrives while collapsed. */
|
|
364
301
|
pulseFab(active) {
|
|
365
302
|
this.#fab?.setAttribute('data-pulse', active ? '1' : '0');
|
|
366
303
|
}
|
|
@@ -370,15 +307,6 @@ export class HudShell {
|
|
|
370
307
|
this.#transitionLock = false;
|
|
371
308
|
}, TRANSITION_LOCK_MS);
|
|
372
309
|
}
|
|
373
|
-
/**
|
|
374
|
-
* A click on the page dismisses the SETTINGS popover - and nothing else.
|
|
375
|
-
*
|
|
376
|
-
* The chat used to close here too, which was wrong from three directions: Reticle's own clicks
|
|
377
|
-
* land on the page (synthetic in-page, or a genuine OS event when it drives through CDP), a click
|
|
378
|
-
* in annotate mode is placing a mark, and a person clicking around their app while watching the
|
|
379
|
-
* log is not asking for the log to go away. The chat has three deliberate ways out - its minimise
|
|
380
|
-
* button, the toolbar toggle, and Escape - and that is all it needs.
|
|
381
|
-
*/
|
|
382
310
|
#onDocPointerDown = (e) => {
|
|
383
311
|
if (this.#root === undefined || this.#dock === undefined)
|
|
384
312
|
return;
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* All presenter overlay CSS - glow border, synthetic cursor/ring/ripple, and the floating HUD shell.
|
|
3
|
-
* Split across shell-styles + controls + log modules so each file stays under the size cap.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* The presenter overlay's stacking layer. Exported because the annotator has to sit ABOVE it: the
|
|
7
|
-
* overlay holds the page blocker, and anything below this number is covered by that shield - which
|
|
8
|
-
* is what buried the annotate composer and made its Cancel/Add buttons unclickable.
|
|
9
|
-
*/
|
|
10
1
|
export declare const Z_OVERLAY = 2147483600;
|
|
11
2
|
export declare const PRESENTER_CSS: string;
|
|
@@ -4,15 +4,6 @@ import { SHELL_CSS } from './presenter-shell-styles.js';
|
|
|
4
4
|
import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
5
5
|
import { HUD_CHROME_CSS, HUD_LOG_WELL_CSS } from './presenter-hud-chrome.js';
|
|
6
6
|
import { REPORT_CSS } from './presenter-report-styles.js';
|
|
7
|
-
/**
|
|
8
|
-
* All presenter overlay CSS - glow border, synthetic cursor/ring/ripple, and the floating HUD shell.
|
|
9
|
-
* Split across shell-styles + controls + log modules so each file stays under the size cap.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* The presenter overlay's stacking layer. Exported because the annotator has to sit ABOVE it: the
|
|
13
|
-
* overlay holds the page blocker, and anything below this number is covered by that shield - which
|
|
14
|
-
* is what buried the annotate composer and made its Cancel/Add buttons unclickable.
|
|
15
|
-
*/
|
|
16
7
|
export const Z_OVERLAY = 2147483600;
|
|
17
8
|
export const PRESENTER_CSS = `
|
|
18
9
|
[data-reticle-overlay]{position:fixed;inset:0;pointer-events:none;z-index:${String(Z_OVERLAY)};}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { type LogResult } from './presenter-log.js';
|
|
2
|
-
/**
|
|
3
|
-
* Paint the live verdict tally into a YouTube-style segmented pill (pass | fail).
|
|
4
|
-
*/
|
|
5
2
|
export declare function renderTally(el: HTMLElement | undefined, runLog: {
|
|
6
3
|
result?: LogResult;
|
|
7
4
|
}[], prev: TallyCounts): TallyCounts;
|
|
8
|
-
/** Running verdict counts the header tally shows - the testing score the human watches grow. */
|
|
9
5
|
export interface TallyCounts {
|
|
10
6
|
passes: number;
|
|
11
7
|
fails: number;
|
|
12
8
|
}
|
|
13
|
-
/** Count pass/fail verdicts across the run log. Pure - no DOM, unit-testable. */
|
|
14
9
|
export declare function countVerdicts(runLog: {
|
|
15
10
|
result?: LogResult;
|
|
16
11
|
}[]): TallyCounts;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { LOG_RESULT } from './presenter-log.js';
|
|
2
2
|
import { PresenterIcon, PRESENTER_ICON_SIZE, hiIcon } from './presenter-icons.js';
|
|
3
|
-
/**
|
|
4
|
-
* Paint the live verdict tally into a YouTube-style segmented pill (pass | fail).
|
|
5
|
-
*/
|
|
6
3
|
export function renderTally(el, runLog, prev) {
|
|
7
4
|
const next = countVerdicts(runLog);
|
|
8
5
|
if (el === undefined)
|
|
@@ -48,7 +45,6 @@ export function renderTally(el, runLog, prev) {
|
|
|
48
45
|
el.append(pass, sep, fail);
|
|
49
46
|
return next;
|
|
50
47
|
}
|
|
51
|
-
/** Count pass/fail verdicts across the run log. Pure - no DOM, unit-testable. */
|
|
52
48
|
export function countVerdicts(runLog) {
|
|
53
49
|
let passes = 0;
|
|
54
50
|
let fails = 0;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
/** Shared fixtures for the presenter test suites (presenter.test.ts + presenter-lifecycle.test.ts). */
|
|
2
1
|
export declare const FAST_IDLE_MS = 20;
|
|
3
2
|
export declare const FAST_FADE_MS = 5;
|
|
4
3
|
export declare const flush: () => Promise<void>;
|
|
5
4
|
export declare const wait: (ms: number) => Promise<void>;
|
|
6
|
-
/** Poll a predicate until true or timeout - robust to real-timer lateness under load (no flake). */
|
|
7
5
|
export declare const until: (pred: () => boolean, ms?: number) => Promise<boolean>;
|
|
8
6
|
export declare const dataOn: () => string | null;
|
|
9
7
|
export declare const dataBusy: () => string | null;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
/** Shared fixtures for the presenter test suites (presenter.test.ts + presenter-lifecycle.test.ts). */
|
|
2
1
|
export const FAST_IDLE_MS = 20;
|
|
3
2
|
export const FAST_FADE_MS = 5;
|
|
4
3
|
export const flush = () => new Promise((r) => setTimeout(r, 0));
|
|
5
4
|
export const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
-
/** Poll a predicate until true or timeout - robust to real-timer lateness under load (no flake). */
|
|
7
5
|
export const until = async (pred, ms = 1000) => {
|
|
8
6
|
const t0 = Date.now();
|
|
9
7
|
while (!pred()) {
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
// Present-tense verb for an action label in the presenter HUD (cursor status + act-log row).
|
|
2
|
-
// Presenter-only UI copy - never a wire string. Shared by presenter.ts (cursor) and reticle.ts
|
|
3
|
-
// (act-log row) so the two stay in lockstep.
|
|
4
|
-
//
|
|
5
|
-
// The CASES are wire values though, and they are core's ActionType. Spelled as free strings here,
|
|
6
|
-
// a rename in core left this switch silently falling through to `default` - which returns the raw
|
|
7
|
-
// action name, so the HUD degrades to "webmcp Save" instead of a verb and nothing fails.
|
|
8
1
|
import { ActionType } from '@reticlehq/core';
|
|
9
2
|
export function actionVerb(action) {
|
|
10
3
|
switch (action) {
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
/** Read the Vite-injected repo root, when present. */
|
|
2
1
|
export declare function readWorkspaceRoot(): string | undefined;
|
|
3
|
-
/** Last path segment for compact display (Codex/Cursor-style chip). */
|
|
4
2
|
export declare function workspaceFolderLabel(root: string): string;
|
|
5
|
-
/** Project id from the URL lease stamp, when present. */
|
|
6
3
|
export declare function readProjectIdFromUrl(): string | undefined;
|
|
7
4
|
export declare function workspaceSummary(): {
|
|
8
5
|
folder: string;
|
|
9
6
|
root?: string;
|
|
10
7
|
projectId?: string;
|
|
11
8
|
};
|
|
12
|
-
/** Workspace chip + detail menu - sits above the composer row. */
|
|
13
9
|
export declare function workspaceRowHtml(): string;
|
|
14
10
|
export declare function paintWorkspace(root: HTMLElement): void;
|
|
15
11
|
export declare function mountWorkspaceSelector(root: HTMLElement): () => void;
|
|
@@ -11,19 +11,16 @@ const PROJECT_LABEL = 'Project';
|
|
|
11
11
|
const COPY_PATH_LABEL = 'Copy path';
|
|
12
12
|
const COPIED_PATH_LABEL = 'Copied';
|
|
13
13
|
const WORKSPACE_FALLBACK = 'This page';
|
|
14
|
-
/** Read the Vite-injected repo root, when present. */
|
|
15
14
|
export function readWorkspaceRoot() {
|
|
16
15
|
const value = globalThis[RETICLE_ROOT_GLOBAL];
|
|
17
16
|
return 'string' === typeof value && value.length > 0 ? value : undefined;
|
|
18
17
|
}
|
|
19
|
-
/** Last path segment for compact display (Codex/Cursor-style chip). */
|
|
20
18
|
export function workspaceFolderLabel(root) {
|
|
21
19
|
const normalized = root.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
22
20
|
const parts = normalized.split('/').filter((part) => part.length > 0);
|
|
23
21
|
const last = parts[parts.length - 1];
|
|
24
22
|
return last !== undefined && last.length > 0 ? last : WORKSPACE_FALLBACK;
|
|
25
23
|
}
|
|
26
|
-
/** Project id from the URL lease stamp, when present. */
|
|
27
24
|
export function readProjectIdFromUrl() {
|
|
28
25
|
if ('undefined' === typeof window)
|
|
29
26
|
return undefined;
|
|
@@ -43,7 +40,6 @@ export function workspaceSummary() {
|
|
|
43
40
|
out.projectId = projectId;
|
|
44
41
|
return out;
|
|
45
42
|
}
|
|
46
|
-
/** Workspace chip + detail menu - sits above the composer row. */
|
|
47
43
|
export function workspaceRowHtml() {
|
|
48
44
|
const folderIcon = hiIconHtml(PresenterIcon.LAYOUT, PRESENTER_ICON_SIZE.HELP);
|
|
49
45
|
const caret = hiIconHtml(PresenterIcon.CARET_DOWN, PRESENTER_ICON_SIZE.HELP);
|
|
@@ -54,7 +50,7 @@ export function workspaceRowHtml() {
|
|
|
54
50
|
<span class="reticle-workspace-name" ${WORKSPACE_NAME_ATTR}>${WORKSPACE_FALLBACK}</span>
|
|
55
51
|
<span class="reticle-workspace-caret" aria-hidden="true">${caret}</span>
|
|
56
52
|
</button>
|
|
57
|
-
<div class="reticle-workspace-menu" ${WORKSPACE_MENU_ATTR} role="
|
|
53
|
+
<div class="reticle-workspace-menu" ${WORKSPACE_MENU_ATTR} role="region" aria-label="${WORKSPACE_LABEL}" aria-hidden="true" hidden>
|
|
58
54
|
<div class="reticle-workspace-menu-head">
|
|
59
55
|
<div class="reticle-workspace-menu-title">${WORKSPACE_LABEL}</div>
|
|
60
56
|
<button type="button" class="reticle-workspace-copy" ${WORKSPACE_COPY_ATTR} title="${COPY_PATH_LABEL}" aria-label="${COPY_PATH_LABEL}">${copyIcon}</button>
|
|
@@ -67,9 +63,6 @@ export function workspaceRowHtml() {
|
|
|
67
63
|
}
|
|
68
64
|
export function paintWorkspace(root) {
|
|
69
65
|
const summary = workspaceSummary();
|
|
70
|
-
// Nothing to say - no injected repo root, no leased project id - so the chip says nothing. It
|
|
71
|
-
// used to render its fallback, "This page", which names no workspace and is exactly as true of
|
|
72
|
-
// every page. The chip earns its slot only when it can tell you WHICH checkout is being driven.
|
|
73
66
|
const wrap = root.querySelector('.reticle-workspace-wrap');
|
|
74
67
|
if (wrap instanceof HTMLElement) {
|
|
75
68
|
const known = summary.root !== undefined || summary.projectId !== undefined;
|
|
@@ -12,93 +12,33 @@ export type { ControlIntent, ControlHandler } from './presenter-controls.js';
|
|
|
12
12
|
export declare class Presenter {
|
|
13
13
|
#private;
|
|
14
14
|
constructor(options?: PresenterOptions);
|
|
15
|
-
/** Setter so reticle.ts can wire the control callback after construction. */
|
|
16
15
|
setControlHandler(handler: ControlHandler): void;
|
|
17
|
-
/** Current live-control session state mirrored onto the panel (data-reticle-state). */
|
|
18
16
|
get state(): SessionState;
|
|
19
|
-
/** Whether a run is currently being presented (false before the agent's first activity / after end). */
|
|
20
17
|
get sessionActive(): boolean;
|
|
21
|
-
/** Drive the panel's live-control visual state (server-push / agent path; never emits). */
|
|
22
18
|
setState(state: SessionState, text?: string, tone?: PresenterTone): void;
|
|
23
|
-
/** Apply a bridge→browser presenter push: PRESENTER (state echo) or FLOWS (replay list, the human's
|
|
24
|
-
* no-agent replay surface). Owns the wire parsing so the SDK dispatcher stays a thin router;
|
|
25
|
-
* setState-only so an echo can't re-emit. */
|
|
26
|
-
/** Re-scope the replay-flow chips to the current page (called by the SDK on route change). */
|
|
27
19
|
refilterFlows(): void;
|
|
28
20
|
handlePush(command: {
|
|
29
21
|
name: string;
|
|
30
22
|
args: Record<string, unknown>;
|
|
31
23
|
}): void;
|
|
32
|
-
/** Current cap on accumulated log rows. */
|
|
33
24
|
get logMax(): number;
|
|
34
25
|
set logMax(n: number);
|
|
35
26
|
mount(): void;
|
|
36
|
-
/** Wire annotation chrome; expanding the HUD enters annotate mode. */
|
|
37
27
|
bindAnnotator(annotator: Annotator): void;
|
|
38
28
|
destroy(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Session start: in 'session' border mode this fades the base border IN and keeps it on until
|
|
41
|
-
* sessionEnd. Idempotent, and a no-op when unmounted or in 'busy' border mode.
|
|
42
|
-
*/
|
|
43
29
|
sessionStart(): void;
|
|
44
|
-
/**
|
|
45
|
-
* The bridge never answered: show that, rather than showing nothing.
|
|
46
|
-
*
|
|
47
|
-
* An instrumented page with a dead bridge used to be indistinguishable from a page with no
|
|
48
|
-
* Reticle in it — overlay mounted, dock off, nothing on screen. The user cannot tell "I forgot to
|
|
49
|
-
* start the daemon" from "the install did not work", and the commonest cause is the cheapest to
|
|
50
|
-
* say: the port. So the HUD appears, states the URL it tried, and marks itself unreachable so it
|
|
51
|
-
* is never mistaken for a live session.
|
|
52
|
-
*
|
|
53
|
-
* Not an error dialog and not modal: the page is the user's, and a dev overlay that shouts is one
|
|
54
|
-
* they turn off. It is the same capsule they would have had, saying the one thing it knows.
|
|
55
|
-
*/
|
|
56
30
|
showUnreachable(url: string, attempts: number): void;
|
|
57
|
-
/**
|
|
58
|
-
* Session end: hides the log/HUD and (in 'session' mode) clears the base border. Idempotent; a
|
|
59
|
-
* no-op without a prior sessionStart or when unmounted.
|
|
60
|
-
*/
|
|
61
31
|
sessionEnd(): void;
|
|
62
|
-
/**
|
|
63
|
-
* Record agent activity. Idempotent while busy - only the first activity from idle/fading flips
|
|
64
|
-
* the glow on, so a burst never restarts the reticle-pulse animation (no strobe). Subsequent calls
|
|
65
|
-
* just refresh the last-activity timestamp and re-arm the idle check.
|
|
66
|
-
*/
|
|
67
32
|
markActivity(): void;
|
|
68
|
-
/** Re-arm the quiet-window idle check (kept for reticle.ts's finally block). */
|
|
69
33
|
scheduleIdle(): void;
|
|
70
|
-
/** Test/diagnostic accessor for the current glow phase. */
|
|
71
34
|
glowPhase(): import("./presenter-config.js").GlowPhase;
|
|
72
|
-
/** Current intent (reading vs acting), exposed for tests + the watcher. */
|
|
73
35
|
get mode(): PresenterMode;
|
|
74
|
-
/**
|
|
75
|
-
* Set the presenter intent. READING shows a cyan scan + chip and hides the cursor; ACTING
|
|
76
|
-
* keeps the warm cursor/ripple + chip; IDLE clears the chip. Drives color via data-reticle-mode.
|
|
77
|
-
*/
|
|
78
36
|
setMode(mode: PresenterMode): void;
|
|
79
37
|
status(text: string): void;
|
|
80
|
-
/** Agent-tunable idle-end window (reticle_session). Floored so it can't be set uselessly small. */
|
|
81
38
|
setIdleEndMs(ms: number): void;
|
|
82
|
-
/**
|
|
83
|
-
* The exported "run state" for the Copy/Export buttons - everything the page holds about this
|
|
84
|
-
* run: session id, url, duration, capability surface, per-kind counts, and the full activity log.
|
|
85
|
-
* (The full network/console ring-buffer lives server-side; this is the in-page run summary.)
|
|
86
|
-
*/
|
|
87
39
|
runState(): PresenterRunState | Record<string, unknown>;
|
|
88
|
-
/**
|
|
89
|
-
* Append an activity-log row. Accumulates (never overwrites): each call adds a timestamped row
|
|
90
|
-
* with a mode chip + text. Returns a handle to stamp the row's outcome glyph (✓/✗) later, or
|
|
91
|
-
* undefined when unmounted / when the text is empty after trimming.
|
|
92
|
-
*/
|
|
93
40
|
log(kind: LogKind, text: string, result?: LogResult): LogHandle | undefined;
|
|
94
|
-
/** Back-compat: narration appends to the live log (append-only, never overwrites). */
|
|
95
41
|
narrate(text: string, level?: string): LogHandle | undefined;
|
|
96
|
-
/**
|
|
97
|
-
* Mirror the server's session.throttled state onto the HUD border. When throttled (tab
|
|
98
|
-
* backgrounded or stale), the border turns amber so the developer knows actions are no-oping -
|
|
99
|
-
* the same signal the agent already reads from result.session.throttled.
|
|
100
|
-
*/
|
|
101
42
|
setThrottled(throttled: boolean): void;
|
|
102
|
-
/** Fly the cursor to an element, play the action's effect, then pace for the human. */
|
|
103
43
|
beforeAct(refId: string, action: string, label: string): Promise<void>;
|
|
104
44
|
}
|