@reticlehq/browser 2.13.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/actions-dom.d.ts +8 -20
- package/dist/actions/actions-dom.js +70 -69
- package/dist/actions/actions-press.d.ts +14 -0
- package/dist/actions/actions-press.js +123 -0
- package/dist/actions/actions.d.ts +1 -89
- package/dist/actions/actions.js +64 -365
- package/dist/actions/appeared-text.d.ts +0 -20
- package/dist/actions/appeared-text.js +6 -36
- package/dist/actions/danger-context.d.ts +3 -0
- package/dist/actions/danger-context.js +39 -0
- package/dist/actions/scroll.d.ts +8 -10
- package/dist/actions/scroll.js +28 -17
- package/dist/actions/synthetic/synthetic-input.d.ts +2 -0
- package/dist/actions/synthetic/synthetic-input.js +13 -0
- 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 +10 -70
- package/dist/connect-options.d.ts +2 -96
- package/dist/dom/a11y.d.ts +0 -29
- package/dist/dom/a11y.js +3 -90
- package/dist/dom/addressing/auto-anchor.d.ts +25 -0
- package/dist/dom/addressing/auto-anchor.js +41 -0
- package/dist/dom/addressing/refs.d.ts +14 -0
- package/dist/dom/addressing/refs.js +114 -0
- package/dist/dom/addressing/source.d.ts +9 -0
- package/dist/dom/addressing/source.js +29 -0
- 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 +1 -73
- package/dist/dom/dom-ignore.d.ts +0 -30
- package/dist/dom/dom-ignore.js +1 -48
- package/dist/dom/occlusion.d.ts +0 -7
- package/dist/dom/occlusion.js +31 -12
- package/dist/dom/paint-context.d.ts +6 -0
- package/dist/dom/paint-context.js +38 -0
- package/dist/dom/query.d.ts +0 -14
- package/dist/dom/query.js +50 -216
- package/dist/dom/realm.d.ts +0 -20
- package/dist/dom/realm.js +0 -28
- 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 +27 -152
- 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 +1 -23
- package/dist/edit-epoch.js +1 -53
- package/dist/index.d.ts +4 -5
- package/dist/index.js +4 -28
- package/dist/observers/animation.d.ts +0 -1
- package/dist/observers/animation.js +1 -4
- package/dist/observers/blind-spots.d.ts +0 -26
- package/dist/observers/blind-spots.js +3 -62
- 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 +28 -52
- package/dist/observers/download.d.ts +1 -2
- package/dist/observers/download.js +39 -56
- 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 +2 -34
- 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/net-detail/network-body.d.ts +12 -0
- package/dist/observers/net-detail/network-body.js +71 -0
- package/dist/observers/net-detail/network-redact.d.ts +1 -0
- package/dist/observers/net-detail/network-redact.js +1 -0
- package/dist/observers/network-stream.d.ts +0 -21
- package/dist/observers/network-stream.js +3 -46
- package/dist/observers/network.d.ts +3 -27
- package/dist/observers/network.js +178 -295
- 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 +2 -11
- 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/chrome/layers.d.ts +2 -0
- package/dist/presenter/chrome/layers.js +2 -0
- package/dist/presenter/chrome/log-kinds.d.ts +12 -0
- package/dist/presenter/chrome/log-kinds.js +7 -0
- package/dist/presenter/{overlay.d.ts → chrome/overlay.d.ts} +0 -1
- package/dist/presenter/{overlay.js → chrome/overlay.js} +0 -1
- package/dist/presenter/chrome/presenter-brand.d.ts +3 -0
- package/dist/presenter/{presenter-brand.js → chrome/presenter-brand.js} +0 -21
- package/dist/presenter/chrome/presenter-effects.d.ts +4 -0
- package/dist/presenter/{presenter-effects.js → chrome/presenter-effects.js} +1 -10
- package/dist/presenter/chrome/presenter-hud-chrome.d.ts +7 -0
- package/dist/presenter/{presenter-hud-chrome.js → chrome/presenter-hud-chrome.js} +0 -10
- package/dist/presenter/chrome/presenter-log.d.ts +17 -0
- package/dist/presenter/{presenter-log.js → chrome/presenter-log.js} +5 -54
- package/dist/presenter/chrome/presenter-report-copy.d.ts +51 -0
- package/dist/presenter/chrome/presenter-report-copy.js +95 -0
- package/dist/presenter/chrome/presenter-safe-html.d.ts +2 -0
- package/dist/presenter/chrome/presenter-safe-html.js +16 -0
- package/dist/presenter/{presenter-tally.d.ts → chrome/presenter-tally.d.ts} +0 -5
- package/dist/presenter/{presenter-tally.js → chrome/presenter-tally.js} +1 -5
- package/dist/presenter/{presenter-verbs.js → chrome/presenter-verbs.js} +0 -7
- package/dist/presenter/{presenter-heroicons-data.d.ts → icons/presenter-heroicons-data.d.ts} +1 -8
- package/dist/presenter/{presenter-heroicons-data.js → icons/presenter-heroicons-data.js} +1 -8
- package/dist/presenter/{presenter-icons.d.ts → icons/presenter-icons.d.ts} +1 -6
- package/dist/presenter/{presenter-icons.js → icons/presenter-icons.js} +1 -6
- package/dist/presenter/presenter-account-styles.d.ts +1 -0
- package/dist/presenter/presenter-account-styles.js +99 -0
- package/dist/presenter/presenter-account.d.ts +40 -0
- package/dist/presenter/presenter-account.js +178 -0
- package/dist/presenter/presenter-config.d.ts +10 -107
- package/dist/presenter/presenter-config.js +5 -92
- package/dist/presenter/presenter-controls.d.ts +1 -35
- package/dist/presenter/presenter-controls.js +10 -133
- package/dist/presenter/presenter-dock-layout.d.ts +0 -3
- package/dist/presenter/presenter-dock-layout.js +1 -5
- package/dist/presenter/presenter-drag.d.ts +2 -42
- package/dist/presenter/presenter-drag.js +3 -76
- package/dist/presenter/presenter-glow.d.ts +0 -21
- package/dist/presenter/presenter-glow.js +2 -28
- package/dist/presenter/presenter-hud-position.d.ts +18 -0
- package/dist/presenter/presenter-hud-position.js +50 -0
- package/dist/presenter/presenter-report-styles.d.ts +0 -6
- package/dist/presenter/presenter-report-styles.js +22 -7
- package/dist/presenter/presenter-report.d.ts +5 -7
- package/dist/presenter/presenter-report.js +44 -95
- package/dist/presenter/presenter-run-state.d.ts +1 -8
- package/dist/presenter/presenter-run-state.js +1 -6
- package/dist/presenter/presenter-settings-styles.d.ts +0 -1
- package/dist/presenter/presenter-settings-styles.js +2 -2
- package/dist/presenter/presenter-settings.d.ts +5 -23
- package/dist/presenter/presenter-settings.js +21 -33
- package/dist/presenter/presenter-shell-styles.js +23 -20
- package/dist/presenter/presenter-shell.d.ts +6 -18
- package/dist/presenter/presenter-shell.js +26 -77
- package/dist/presenter/presenter-styles.d.ts +2 -10
- package/dist/presenter/presenter-styles.js +6 -12
- package/dist/presenter/presenter-workspace.d.ts +4 -4
- package/dist/presenter/presenter-workspace.js +30 -10
- package/dist/presenter/presenter.d.ts +3 -63
- package/dist/presenter/presenter.js +29 -132
- package/dist/presenter/tour/tour-view.d.ts +33 -0
- package/dist/presenter/tour/tour-view.js +188 -0
- package/dist/presenter/tour/tour.d.ts +25 -0
- package/dist/presenter/tour/tour.js +245 -0
- 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 +6 -49
- 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/declared-channels.d.ts +2 -0
- package/dist/registry/declared-channels.js +14 -0
- package/dist/registry/declared-platform.d.ts +4 -0
- package/dist/registry/declared-platform.js +34 -0
- 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 +1 -11
- package/dist/registry/store-adapters.d.ts +0 -186
- package/dist/registry/store-adapters.js +1 -164
- package/dist/registry/{adapters.d.ts → stores/adapters.d.ts} +0 -10
- package/dist/registry/{adapters.js → stores/adapters.js} +0 -10
- package/dist/registry/stores.d.ts +0 -33
- package/dist/registry/stores.js +1 -60
- package/dist/reticle-presenter-helpers.d.ts +0 -13
- package/dist/reticle-presenter-helpers.js +10 -20
- package/dist/reticle-singleton.d.ts +2 -0
- package/dist/reticle-singleton.js +3 -0
- package/dist/reticle.d.ts +1 -52
- package/dist/reticle.js +115 -180
- package/dist/review/annotator-styles.js +1 -8
- package/dist/review/annotator.d.ts +2 -13
- package/dist/review/annotator.js +2 -42
- package/dist/review/mark-anchor.d.ts +0 -11
- package/dist/review/mark-anchor.js +3 -11
- 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/console/native-console.js +5 -0
- package/dist/timers/native/native-timers.d.ts +11 -0
- package/dist/timers/native/native-timers.js +48 -0
- package/dist/transport/transport.d.ts +0 -51
- package/dist/transport/transport.js +5 -131
- 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 +5 -4
- package/dist/actions/synthetic-input.d.ts +0 -9
- package/dist/actions/synthetic-input.js +0 -40
- package/dist/dom/auto-anchor.d.ts +0 -65
- package/dist/dom/auto-anchor.js +0 -74
- package/dist/dom/refs.d.ts +0 -90
- package/dist/dom/refs.js +0 -245
- package/dist/dom/source.d.ts +0 -53
- package/dist/dom/source.js +0 -74
- package/dist/observers/network-body.d.ts +0 -35
- package/dist/observers/network-body.js +0 -168
- package/dist/observers/network-redact.d.ts +0 -20
- package/dist/observers/network-redact.js +0 -80
- package/dist/presenter/presenter-brand.d.ts +0 -22
- package/dist/presenter/presenter-effects.d.ts +0 -13
- package/dist/presenter/presenter-hud-chrome.d.ts +0 -17
- package/dist/presenter/presenter-log.d.ts +0 -64
- package/dist/presenter/presenter-report-copy.d.ts +0 -112
- package/dist/presenter/presenter-report-copy.js +0 -156
- package/dist/presenter/presenter-test-helpers.d.ts +0 -16
- package/dist/presenter/presenter-test-helpers.js +0 -41
- package/dist/timers/native-console.js +0 -9
- package/dist/timers/native-timers.d.ts +0 -36
- package/dist/timers/native-timers.js +0 -78
- /package/dist/presenter/{presenter-verbs.d.ts → chrome/presenter-verbs.d.ts} +0 -0
- /package/dist/timers/{native-console.d.ts → console/native-console.d.ts} +0 -0
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { SessionState } from '@reticlehq/core';
|
|
2
|
-
import { LOG_KIND, LOG_RESULT } from './presenter-log.js';
|
|
2
|
+
import { LOG_KIND, LOG_RESULT } from './chrome/presenter-log.js';
|
|
3
3
|
import { getCapabilities } from '../registry/capabilities.js';
|
|
4
|
-
/**
|
|
5
|
-
* Compute the exported run-state from the controller's live fields: per-kind + pass/fail counts over
|
|
6
|
-
* the activity log, the session duration, and the current capability surface. Extracted from
|
|
7
|
-
* presenter.ts so the controller stays under the size cap; the counting is the same as before.
|
|
8
|
-
*/
|
|
9
4
|
export function buildRunState(input) {
|
|
10
5
|
const start = input.startMs ?? input.now;
|
|
11
6
|
const counts = { reads: 0, acts: 0, narrations: 0, human: 0, passes: 0, fails: 0 };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SETTINGS_PANEL_ATTR, SETTINGS_ATTR, DOCK_ATTR, DOCK_ALIGN_ATTR, SETTINGS_PLACEMENT_ATTR, } from './presenter-config.js';
|
|
2
|
-
import { HUD_DROP_SHADOW, HUD_SURFACE_CLASS, HUD_SURFACE_PAINT } from './presenter-hud-chrome.js';
|
|
3
|
-
/** Compact settings card - dock-anchored above the HUD pill. */
|
|
2
|
+
import { HUD_DROP_SHADOW, HUD_SURFACE_CLASS, HUD_SURFACE_PAINT, } from './chrome/presenter-hud-chrome.js';
|
|
4
3
|
export const SETTINGS_CSS = `
|
|
5
4
|
[${'data-reticle-overlay'}][${SETTINGS_ATTR}="1"] [${'data-reticle-chat-panel'}]{
|
|
6
5
|
display:none !important;visibility:hidden !important;pointer-events:none !important;}
|
|
@@ -150,4 +149,5 @@ export const SETTINGS_CSS = `
|
|
|
150
149
|
display:none;pointer-events:none;}
|
|
151
150
|
[${'data-reticle-overlay'}][data-reticle-hidden="1"] [${DOCK_ATTR}],
|
|
152
151
|
[${'data-reticle-overlay'}][data-reticle-hidden="1"] [${SETTINGS_PANEL_ATTR}]{display:none !important;}
|
|
152
|
+
|
|
153
153
|
`;
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
2
|
+
import type { AccountState } from '@reticlehq/core';
|
|
3
|
+
import { type AccountDetails } from './presenter-account.js';
|
|
2
4
|
export { SETTINGS_CSS };
|
|
3
|
-
/** How much detail lands in copied/exported run state. */
|
|
4
5
|
export declare const OutputDetail: {
|
|
5
6
|
readonly MINIMAL: "minimal";
|
|
6
7
|
readonly STANDARD: "standard";
|
|
7
8
|
readonly VERBOSE: "verbose";
|
|
8
9
|
};
|
|
9
10
|
export type OutputDetail = (typeof OutputDetail)[keyof typeof OutputDetail];
|
|
10
|
-
/**
|
|
11
|
-
* Status themes: ONE choice, three colours.
|
|
12
|
-
*
|
|
13
|
-
* This was four separate pickers - a chrome accent plus a swatch row per state - which is 28
|
|
14
|
-
* decisions to land on a set that works together. A theme is a combination we have already checked
|
|
15
|
-
* reads as a progression (working -> waiting -> done) and against a dark app, so the choice is
|
|
16
|
-
* "which mood", not "which four hex values".
|
|
17
|
-
*/
|
|
18
11
|
export declare const StatusThemeId: {
|
|
19
12
|
readonly SIGNAL: "signal";
|
|
20
13
|
readonly TRAFFIC: "traffic";
|
|
@@ -23,7 +16,7 @@ export declare const StatusThemeId: {
|
|
|
23
16
|
readonly EMBER: "ember";
|
|
24
17
|
};
|
|
25
18
|
export type StatusThemeId = (typeof StatusThemeId)[keyof typeof StatusThemeId];
|
|
26
|
-
|
|
19
|
+
interface StatusTheme {
|
|
27
20
|
id: StatusThemeId;
|
|
28
21
|
label: string;
|
|
29
22
|
active: string;
|
|
@@ -34,13 +27,7 @@ export declare const STATUS_THEMES: readonly StatusTheme[];
|
|
|
34
27
|
export declare function statusTheme(id: StatusThemeId): StatusTheme;
|
|
35
28
|
export interface PresenterSettings {
|
|
36
29
|
outputDetail: OutputDetail;
|
|
37
|
-
/**
|
|
38
|
-
* The colours the HUD signals session state with - the dot, the panel wash, the page glow, the
|
|
39
|
-
* FAB halo and the annotation marks all read from whichever one is current. One choice, because
|
|
40
|
-
* the three have to work as a set and against the user's own app.
|
|
41
|
-
*/
|
|
42
30
|
statusThemeId: StatusThemeId;
|
|
43
|
-
/** The page-edge glow. Off leaves every other signal (dot, panel, FAB) in place. */
|
|
44
31
|
ambientGlow: boolean;
|
|
45
32
|
reactComponents: boolean;
|
|
46
33
|
hideUntilRestart: boolean;
|
|
@@ -53,21 +40,16 @@ export interface PresenterSettings {
|
|
|
53
40
|
}
|
|
54
41
|
export declare function getPresenterSettings(): PresenterSettings;
|
|
55
42
|
export declare function loadPresenterSettings(): PresenterSettings;
|
|
56
|
-
|
|
43
|
+
export declare const SETTINGS_ACCOUNT_ATTR = "data-reticle-settings-account";
|
|
44
|
+
export declare function paintSettingsAccount(root: HTMLElement, account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
|
|
57
45
|
export declare function settingsPanelHtml(): string;
|
|
58
46
|
export interface SettingsHost {
|
|
59
47
|
onHideUntilRestart?: () => void;
|
|
60
48
|
onSettingsChange?: (settings: PresenterSettings) => void;
|
|
61
49
|
onBeforeOpen?: () => void;
|
|
62
50
|
}
|
|
63
|
-
/** Apply persisted settings onto the overlay + dock. */
|
|
64
51
|
export declare function applyPresenterSettings(root: HTMLElement, settings: PresenterSettings): void;
|
|
65
|
-
/**
|
|
66
|
-
* Toggle the full-page blocker. Only active while annotate mode is live AND the user opted in -
|
|
67
|
-
* never on a collapsed FAB, so real hover/click on the host app still works.
|
|
68
|
-
*/
|
|
69
52
|
export declare function syncPageBlocker(root: HTMLElement, settings: PresenterSettings, annotateLive: boolean): void;
|
|
70
|
-
/** Blocker node - sits under Reticle UI, above the host page. */
|
|
71
53
|
export declare function blockerHtml(): string;
|
|
72
54
|
export declare class PresenterSettingsPanel {
|
|
73
55
|
#private;
|
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
import { SETTINGS_ATTR, SETTINGS_BTN_ATTR, SETTINGS_PANEL_ATTR, SETTINGS_CLOSE_ATTR, SETTING_KEY_ATTR, SETTINGS_STORAGE_KEY, AMBIENT_GLOW_ATTR, BLOCK_ATTR, HIDDEN_UNTIL_RESTART_ATTR, LOG_TIMESTAMPS_ATTR, REDUCE_MOTION_ATTR, DOCK_ATTR, MCP_DOCS_URL, } from './presenter-config.js';
|
|
2
|
-
import { PresenterIcon, PRESENTER_ICON_SIZE, setHiIcon, hiIconHtml } from './presenter-icons.js';
|
|
3
|
-
import { HUD_SURFACE_CLASS } from './presenter-hud-chrome.js';
|
|
2
|
+
import { PresenterIcon, PRESENTER_ICON_SIZE, setHiIcon, hiIconHtml, } from './icons/presenter-icons.js';
|
|
3
|
+
import { HUD_SURFACE_CLASS } from './chrome/presenter-hud-chrome.js';
|
|
4
4
|
import { resetHudDockPosition } from './presenter-drag.js';
|
|
5
5
|
import { findDock, scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
6
6
|
import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
7
|
+
import { accountControlHtml } from './presenter-account.js';
|
|
7
8
|
export { SETTINGS_CSS };
|
|
8
|
-
/** How much detail lands in copied/exported run state. */
|
|
9
9
|
export const OutputDetail = {
|
|
10
10
|
MINIMAL: 'minimal',
|
|
11
11
|
STANDARD: 'standard',
|
|
12
12
|
VERBOSE: 'verbose',
|
|
13
13
|
};
|
|
14
|
-
/**
|
|
15
|
-
* Status themes: ONE choice, three colours.
|
|
16
|
-
*
|
|
17
|
-
* This was four separate pickers - a chrome accent plus a swatch row per state - which is 28
|
|
18
|
-
* decisions to land on a set that works together. A theme is a combination we have already checked
|
|
19
|
-
* reads as a progression (working -> waiting -> done) and against a dark app, so the choice is
|
|
20
|
-
* "which mood", not "which four hex values".
|
|
21
|
-
*/
|
|
22
14
|
export const StatusThemeId = {
|
|
23
15
|
SIGNAL: 'signal',
|
|
24
16
|
TRAFFIC: 'traffic',
|
|
@@ -70,14 +62,6 @@ const DEFAULT_SETTINGS = {
|
|
|
70
62
|
blockPageInteractions: true,
|
|
71
63
|
showTally: false,
|
|
72
64
|
showTimestamps: true,
|
|
73
|
-
// ON by default: the chat IS the HUD's content, and shipping it off meant the default experience
|
|
74
|
-
// was a bare toolbar until somebody found the toggle. `expand()` has always opened the chat for
|
|
75
|
-
// the same reason; this is the other half — session start, with no click at all.
|
|
76
|
-
//
|
|
77
|
-
// Safe to default because `openChat()` expands a collapsed HUD, and session start is the one
|
|
78
|
-
// moment where that is what you want. A user who prefers the bare toolbar turns this off and it
|
|
79
|
-
// stays off: a stored `false` is honoured over the default, which is pinned in
|
|
80
|
-
// presenter-chat-default.test.ts so the product cannot change somebody's answer behind their back.
|
|
81
65
|
autoOpenChat: true,
|
|
82
66
|
reduceMotion: false,
|
|
83
67
|
};
|
|
@@ -101,10 +85,6 @@ export function loadPresenterSettings() {
|
|
|
101
85
|
? o['outputDetail']
|
|
102
86
|
: DEFAULT_SETTINGS.outputDetail,
|
|
103
87
|
reactComponents: true === o['reactComponents'],
|
|
104
|
-
// NOT read back from storage. "Until restart" has to mean until restart: persisted, it
|
|
105
|
-
// survived the reload that was supposed to undo it, and the only way back was clearing
|
|
106
|
-
// localStorage by hand - the HUD was simply gone, including the settings panel that turned
|
|
107
|
-
// it off. It is a this-page-only switch, so it lives only in memory.
|
|
108
88
|
hideUntilRestart: false,
|
|
109
89
|
statusThemeId: isStatusThemeId(o['statusThemeId'])
|
|
110
90
|
? o['statusThemeId']
|
|
@@ -140,7 +120,6 @@ function persistSettings(next) {
|
|
|
140
120
|
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(next));
|
|
141
121
|
}
|
|
142
122
|
catch {
|
|
143
|
-
/* quota / private mode - settings still apply for this page */
|
|
144
123
|
}
|
|
145
124
|
}
|
|
146
125
|
function patchSettings(patch) {
|
|
@@ -168,7 +147,18 @@ function settingsCheckRow(key, label, checked) {
|
|
|
168
147
|
<span class="reticle-settings-check-label">${label}</span>
|
|
169
148
|
</label>`;
|
|
170
149
|
}
|
|
171
|
-
|
|
150
|
+
export const SETTINGS_ACCOUNT_ATTR = 'data-reticle-settings-account';
|
|
151
|
+
const SETTINGS_ACCOUNT_ROW_ATTR = 'data-reticle-settings-account-row';
|
|
152
|
+
const ACCOUNT_HELP = 'Whether this machine is signed in to a Reticle workspace. Signing in happens in your terminal.';
|
|
153
|
+
export function paintSettingsAccount(root, account, dashboardUrl, details = {}) {
|
|
154
|
+
const row = root.querySelector(`[${SETTINGS_ACCOUNT_ROW_ATTR}]`);
|
|
155
|
+
const slot = root.querySelector(`[${SETTINGS_ACCOUNT_ATTR}]`);
|
|
156
|
+
if (!(row instanceof HTMLElement) || !(slot instanceof HTMLElement))
|
|
157
|
+
return;
|
|
158
|
+
const html = accountControlHtml(account, { ...details, dashboardUrl }, true);
|
|
159
|
+
row.hidden = 0 === html.length;
|
|
160
|
+
slot.innerHTML = html;
|
|
161
|
+
}
|
|
172
162
|
export function settingsPanelHtml() {
|
|
173
163
|
const close = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.MIN);
|
|
174
164
|
const caret = hiIconHtml(PresenterIcon.CARET_RIGHT, PRESENTER_ICON_SIZE.HELP);
|
|
@@ -180,7 +170,7 @@ export function settingsPanelHtml() {
|
|
|
180
170
|
const autoChatHelp = 'On by default. Opens the agent chat by itself when a session starts and when you expand the HUD. Off leaves the toolbar bare until you ask for the chat.';
|
|
181
171
|
const motionHelp = 'Reduce HUD animations for accessibility';
|
|
182
172
|
const glowHelp = 'Glow the page edges in the status colour while a session is live. Off keeps the HUD signals and leaves your app alone.';
|
|
183
|
-
return `<div ${SETTINGS_PANEL_ATTR} class="reticle-settings ${HUD_SURFACE_CLASS}" role="
|
|
173
|
+
return `<div ${SETTINGS_PANEL_ATTR} class="reticle-settings ${HUD_SURFACE_CLASS}" role="region" aria-label="Reticle settings" aria-hidden="true">
|
|
184
174
|
<div class="reticle-settings-inner">
|
|
185
175
|
<div class="reticle-settings-head">
|
|
186
176
|
<span class="reticle-settings-title">Settings</span>
|
|
@@ -202,6 +192,11 @@ export function settingsPanelHtml() {
|
|
|
202
192
|
${settingsCheckRow('clearOnCopy', 'Clear on copy/send', false)}
|
|
203
193
|
${settingsToggleRow('hideUntilRestart', 'Hide Until Restart', hideHelp)}
|
|
204
194
|
${settingsToggleRow('reduceMotion', 'Reduce motion', motionHelp)}
|
|
195
|
+
<div class="reticle-settings-section">Account</div>
|
|
196
|
+
<div class="reticle-settings-row" ${SETTINGS_ACCOUNT_ROW_ATTR} hidden>
|
|
197
|
+
${settingsLabel('Workspace', ACCOUNT_HELP)}
|
|
198
|
+
<span ${SETTINGS_ACCOUNT_ATTR}></span>
|
|
199
|
+
</div>
|
|
205
200
|
<div class="reticle-settings-section">Status theme</div>
|
|
206
201
|
${settingsToggleRow('ambientGlow', 'Page glow', glowHelp)}
|
|
207
202
|
<div class="reticle-settings-themes" data-reticle-settings-themes></div>
|
|
@@ -213,7 +208,6 @@ export function settingsPanelHtml() {
|
|
|
213
208
|
</div>
|
|
214
209
|
</div>`;
|
|
215
210
|
}
|
|
216
|
-
/** Apply persisted settings onto the overlay + dock. */
|
|
217
211
|
export function applyPresenterSettings(root, settings) {
|
|
218
212
|
const theme = statusTheme(settings.statusThemeId);
|
|
219
213
|
root.style.setProperty('--reticle-mark-accent', theme.active);
|
|
@@ -235,14 +229,9 @@ export function applyPresenterSettings(root, settings) {
|
|
|
235
229
|
tally.setAttribute('hidden', '');
|
|
236
230
|
}
|
|
237
231
|
}
|
|
238
|
-
/**
|
|
239
|
-
* Toggle the full-page blocker. Only active while annotate mode is live AND the user opted in -
|
|
240
|
-
* never on a collapsed FAB, so real hover/click on the host app still works.
|
|
241
|
-
*/
|
|
242
232
|
export function syncPageBlocker(root, settings, annotateLive) {
|
|
243
233
|
root.setAttribute(BLOCK_ATTR, settings.blockPageInteractions && annotateLive ? '1' : '0');
|
|
244
234
|
}
|
|
245
|
-
/** Blocker node - sits under Reticle UI, above the host page. */
|
|
246
235
|
export function blockerHtml() {
|
|
247
236
|
return '<div data-reticle-blocker aria-hidden="true"></div>';
|
|
248
237
|
}
|
|
@@ -470,7 +459,6 @@ export class PresenterSettingsPanel {
|
|
|
470
459
|
el.textContent = on ? '✓' : '';
|
|
471
460
|
}
|
|
472
461
|
}
|
|
473
|
-
/** One row of themes: each chip shows the whole set - active, idle, ended - in order. */
|
|
474
462
|
#buildThemes() {
|
|
475
463
|
const host = this.#panel?.querySelector('[data-reticle-settings-themes]');
|
|
476
464
|
if (null === host || undefined === host)
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Split from presenter-styles.ts so the controller stays under the size cap.
|
|
4
|
-
*/
|
|
5
|
-
import { LOG_TIME_ATTR } from './presenter-log.js';
|
|
1
|
+
import { LOG_TIME_ATTR } from './chrome/presenter-log.js';
|
|
2
|
+
import { Z_HUD_TOOLTIP } from './presenter-config.js';
|
|
6
3
|
import { CHAT_ATTR, CHAT_PILL_ATTR, CHAT_PLACEMENT_ATTR, DOCK_ALIGN_ATTR, DOCK_ATTR, LOG_TIMESTAMPS_ATTR, MIN_ATTR, REDUCE_MOTION_ATTR, LIVENESS_ATTR, } from './presenter-config.js';
|
|
7
|
-
import { HUD_DROP_SHADOW, HUD_SURFACE_FILL } from './presenter-hud-chrome.js';
|
|
4
|
+
import { HUD_DROP_SHADOW, HUD_SURFACE_FILL } from './chrome/presenter-hud-chrome.js';
|
|
8
5
|
const OVERLAY = 'data-reticle-overlay';
|
|
9
6
|
const HUD = 'data-reticle-hud';
|
|
10
7
|
const CHAT_PANEL = 'data-reticle-chat-panel';
|
|
@@ -89,8 +86,8 @@ export const SHELL_CSS = `
|
|
|
89
86
|
/**
|
|
90
87
|
* Minimising the chat leaves a CAPSULE, not a hole: the same glass, the same state dot, the last
|
|
91
88
|
* thing the agent did - sitting directly above the toolbar capsule and reopening the panel when
|
|
92
|
-
* clicked.
|
|
93
|
-
*
|
|
89
|
+
* clicked. Leaving the toolbar alone above an empty gap would make a minimised session look
|
|
90
|
+
* identical to no session at all.
|
|
94
91
|
*/
|
|
95
92
|
[${CHAT_PILL_ATTR}]{
|
|
96
93
|
display:none;position:absolute;right:0;left:auto;bottom:calc(100% + 8px);z-index:5;
|
|
@@ -118,6 +115,13 @@ export const SHELL_CSS = `
|
|
|
118
115
|
flex:none;display:flex;align-items:center;gap:8px;padding:11px 44px 9px 14px;
|
|
119
116
|
border-bottom:1px solid rgba(255,255,255,.06);}
|
|
120
117
|
[${CHAT_PANEL}] .reticle-chat-brand{display:inline-flex;align-items:center;gap:7px;color:var(--reticle-fg);}
|
|
118
|
+
/* The account capsule lives in the header, not the toolbar. The toolbar row is already 13px over its
|
|
119
|
+
own width, so a 20px avatar there pushed the close button outside the panel. The header has the
|
|
120
|
+
space, is visible under exactly the same condition, and is where an account avatar belongs anyway.
|
|
121
|
+
margin-left:auto right-aligns it; the head reserves 44px of right padding for the caret above it,
|
|
122
|
+
so the two never overlap. The :empty rule keeps the gap closed when no account state was sent. */
|
|
123
|
+
[${CHAT_PANEL}] .reticle-head-account{margin-left:auto;display:inline-flex;align-items:center;}
|
|
124
|
+
[${CHAT_PANEL}] .reticle-head-account:empty{display:none;}
|
|
121
125
|
[${CHAT_PANEL}] .reticle-chat-brand .reticle-mark{height:14px;width:auto;}
|
|
122
126
|
[${CHAT_PANEL}] .reticle-chat-brandname{font-size:12.5px;font-weight:600;letter-spacing:.01em;}
|
|
123
127
|
/* No state word here: the activity strip immediately below already says "idle · 21s", and the
|
|
@@ -237,6 +241,7 @@ export const SHELL_CSS = `
|
|
|
237
241
|
padding:2px;border-radius:999px;background:rgba(0,0,0,.2);}
|
|
238
242
|
[${HUD}] .reticle-toolbar-chrome{display:inline-flex;align-items:center;gap:2px;flex:none;}
|
|
239
243
|
[${HUD}] .reticle-tb-sep{width:1px;height:14px;background:rgba(255,255,255,.12);margin:0 4px;flex:none;align-self:center;}
|
|
244
|
+
|
|
240
245
|
[${HUD}] .reticle-tb-wrap{position:relative;display:flex;align-items:center;justify-content:center;overflow:visible;}
|
|
241
246
|
[${HUD}] .reticle-tb-btn{
|
|
242
247
|
flex:none;display:inline-flex;align-items:center;justify-content:center;
|
|
@@ -262,10 +267,9 @@ export const SHELL_CSS = `
|
|
|
262
267
|
[${HUD}] .reticle-hi-toggle .reticle-hi-icon--solid svg{
|
|
263
268
|
transform:scale(1.12);transform-origin:center;}
|
|
264
269
|
/*
|
|
265
|
-
* Active toggles keep the OUTLINE icon.
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* which is enough and does not change the icon's weight.
|
|
270
|
+
* Active toggles keep the OUTLINE icon. The solid heroicon is a filled glyph next to 1.5px strokes
|
|
271
|
+
* everywhere else, so a pressed button reads as a heavier typeface rather than as a state. Accent
|
|
272
|
+
* colour and the background above already carry the state without changing the icon's weight.
|
|
269
273
|
*/
|
|
270
274
|
[${HUD}] .reticle-tb-btn--toggle[data-active="1"] .reticle-hi-icon--outline{opacity:1;}
|
|
271
275
|
[${HUD}] .reticle-tb-btn--toggle .reticle-hi-icon--solid{opacity:0;}
|
|
@@ -277,10 +281,10 @@ export const SHELL_CSS = `
|
|
|
277
281
|
/**
|
|
278
282
|
* The toolbar is a FIXED number of slots.
|
|
279
283
|
*
|
|
280
|
-
* Copy and Export appear when a session ends, and
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
+
* Copy and Export appear when a session ends, and the bar is already full - eleven icons in a pill
|
|
285
|
+
* sized for nine renders the last one outside the rounded box. They take the two slots Pause and End
|
|
286
|
+
* vacate: neither can do anything to an ended session, so the bar swaps two dead controls for two
|
|
287
|
+
* live ones and never changes width.
|
|
284
288
|
*/
|
|
285
289
|
[${HUD}] .reticle-tb-btn--export{display:none;}
|
|
286
290
|
[${OVERLAY}][${STATE}="ended"] [${HUD}] .reticle-tb-btn--export{display:inline-flex;}
|
|
@@ -289,7 +293,7 @@ export const SHELL_CSS = `
|
|
|
289
293
|
[${HUD}] .reticle-tb-tip{
|
|
290
294
|
position:absolute;bottom:calc(100% + 14px);left:50%;transform:translateX(-50%) scale(.95);
|
|
291
295
|
padding:6px 10px;background:#1a1a1a;color:rgba(255,255,255,.9);font-size:12px;font-weight:500;
|
|
292
|
-
border-radius:8px;white-space:nowrap;opacity:0;visibility:hidden;pointer-events:none;z-index
|
|
296
|
+
border-radius:8px;white-space:nowrap;opacity:0;visibility:hidden;pointer-events:none;z-index:${String(Z_HUD_TOOLTIP)};
|
|
293
297
|
box-shadow:0 2px 8px rgba(0,0,0,.3);transition:opacity .135s ease,transform .135s ease,visibility .135s;}
|
|
294
298
|
[${HUD}] .reticle-tb-tip::after{
|
|
295
299
|
content:"";position:absolute;top:calc(100% - 4px);left:50%;transform:translateX(-50%) rotate(45deg);
|
|
@@ -310,9 +314,8 @@ export const SHELL_CSS = `
|
|
|
310
314
|
* The mode, ON the status row rather than under it.
|
|
311
315
|
*
|
|
312
316
|
* The action text beside it is flex:1, so this claims the right edge of the row and takes its space
|
|
313
|
-
* from the elided action text. Nothing above or below moves:
|
|
314
|
-
*
|
|
315
|
-
* second UI appearing and leaving.
|
|
317
|
+
* from the elided action text. Nothing above or below moves: growing and shrinking by the height of
|
|
318
|
+
* this pill on every tool call makes one status line look like a second UI appearing and leaving.
|
|
316
319
|
*/
|
|
317
320
|
[${DOCK_ATTR}] .reticle-chip{display:none;flex:none;align-items:center;gap:4px;font-size:8px;font-weight:600;letter-spacing:.06em;
|
|
318
321
|
height:16px;padding:0 7px;line-height:1;border-radius:999px;text-transform:uppercase;
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import { PresenterReport } from './presenter-report.js';
|
|
2
|
+
import type { AccountState } from '@reticlehq/core';
|
|
3
|
+
import { type AccountDetails } from './presenter-account.js';
|
|
2
4
|
import { type SettingsHost } from './presenter-settings.js';
|
|
3
|
-
|
|
5
|
+
interface HudShellCallbacks {
|
|
4
6
|
onChatOpen?: () => void;
|
|
5
7
|
onChatClose?: () => void;
|
|
6
8
|
onExpand?: () => void;
|
|
7
|
-
/** The user pressed the annotate toggle. `on` is the state they asked for. */
|
|
8
9
|
onAnnotateToggle?: (on: boolean) => void;
|
|
9
10
|
onCollapse?: () => void;
|
|
11
|
+
onSyncNow?: () => void;
|
|
10
12
|
settings?: SettingsHost;
|
|
11
13
|
}
|
|
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
14
|
export declare class HudShell {
|
|
17
15
|
#private;
|
|
16
|
+
paintAccount(account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
|
|
18
17
|
constructor(callbacks?: HudShellCallbacks);
|
|
19
|
-
/** Markup for the dock wrapper (chat panel + morphing HUD shell). */
|
|
20
18
|
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
19
|
get report(): PresenterReport;
|
|
23
|
-
/** Does the user currently want to annotate? */
|
|
24
20
|
isAnnotateOn(): boolean;
|
|
25
|
-
/** Set the toggle and reflect it on the button, without firing the callback. */
|
|
26
21
|
setAnnotateOn(on: boolean): void;
|
|
27
22
|
mount(root: HTMLElement): void;
|
|
28
23
|
teardown(): void;
|
|
@@ -33,14 +28,7 @@ export declare class HudShell {
|
|
|
33
28
|
openChat(): void;
|
|
34
29
|
closeChat(): void;
|
|
35
30
|
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
31
|
showChat(): void;
|
|
44
|
-
/** Pulse the FAB when new activity arrives while collapsed. */
|
|
45
32
|
pulseFab(active: boolean): void;
|
|
46
33
|
}
|
|
34
|
+
export {};
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import { PresenterReport, reportPanelHtml } from './presenter-report.js';
|
|
2
|
+
import { paintToolbarAccount, TOOLBAR_ACCOUNT_ATTR } from './presenter-workspace.js';
|
|
3
|
+
import { mountAccountControl } from './presenter-account.js';
|
|
4
|
+
import { paintSettingsAccount } from './presenter-settings.js';
|
|
2
5
|
import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, REPORT_BTN_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, } from './presenter-config.js';
|
|
3
|
-
import { BRAND_NAME, FAB_TOGGLE_HTML, MARK_SVG } from './presenter-brand.js';
|
|
4
|
-
import { settleLogAtLatest } from './presenter-log.js';
|
|
6
|
+
import { BRAND_NAME, FAB_TOGGLE_HTML, MARK_SVG } from './chrome/presenter-brand.js';
|
|
7
|
+
import { settleLogAtLatest } from './chrome/presenter-log.js';
|
|
5
8
|
import { installHudDragHandles, installHudPositionGuards } from './presenter-drag.js';
|
|
6
9
|
import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
7
|
-
import { hiIconHtml, hiToggleIconHtml, PRESENTER_ICON_SIZE, PresenterIcon, } from './presenter-icons.js';
|
|
8
|
-
import { HUD_SURFACE_CLASS, HUD_LOG_WELL_CLASS } from './presenter-hud-chrome.js';
|
|
10
|
+
import { hiIconHtml, hiToggleIconHtml, PRESENTER_ICON_SIZE, PresenterIcon, } from './icons/presenter-icons.js';
|
|
11
|
+
import { HUD_SURFACE_CLASS, HUD_LOG_WELL_CLASS } from './chrome/presenter-hud-chrome.js';
|
|
9
12
|
import { CONTROLS_TOOLBAR_HTML } from './presenter-controls.js';
|
|
10
13
|
import { PresenterSettingsPanel, settingsPanelHtml, } from './presenter-settings.js';
|
|
11
14
|
const DRAG_HANDLE_CLASS = 'reticle-toolbar-drag';
|
|
12
15
|
const TRANSITION_LOCK_MS = 120;
|
|
13
16
|
const ANNOTATE_LABEL = 'Annotate';
|
|
14
17
|
const CHAT_MIN_LABEL = 'Minimise chat';
|
|
15
|
-
/** The minimised chat capsule's label - it reopens the panel. */
|
|
16
18
|
const CHAT_PILL_LABEL = 'Open agent chat';
|
|
17
|
-
/** The toolbar entry to the impact report. */
|
|
18
19
|
const REPORT_LABEL = 'Impact';
|
|
19
20
|
const SETTINGS_LABEL = 'Settings';
|
|
20
21
|
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
22
|
export class HudShell {
|
|
26
23
|
#root;
|
|
27
24
|
#dock;
|
|
@@ -35,60 +32,47 @@ export class HudShell {
|
|
|
35
32
|
#transitionLock = false;
|
|
36
33
|
#suppressFabClick = false;
|
|
37
34
|
#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
35
|
#annotateOn = false;
|
|
50
36
|
#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
37
|
#listeners;
|
|
60
38
|
#report = new PresenterReport({
|
|
61
39
|
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
40
|
this.#settings.close();
|
|
65
41
|
this.closeChat();
|
|
66
42
|
},
|
|
43
|
+
onSyncNow: () => this.#callbacks.onSyncNow?.(),
|
|
67
44
|
});
|
|
68
45
|
#callbacks;
|
|
46
|
+
#pushedAccount;
|
|
47
|
+
#accountTeardown;
|
|
48
|
+
paintAccount(account, dashboardUrl, details = {}) {
|
|
49
|
+
this.#pushedAccount = { account, dashboardUrl, details };
|
|
50
|
+
if (this.#root === undefined)
|
|
51
|
+
return;
|
|
52
|
+
paintToolbarAccount(this.#root, account, dashboardUrl, details);
|
|
53
|
+
paintSettingsAccount(this.#root, account, dashboardUrl, details);
|
|
54
|
+
}
|
|
69
55
|
constructor(callbacks = {}) {
|
|
70
56
|
this.#callbacks = callbacks;
|
|
71
57
|
this.#settings = new PresenterSettingsPanel({
|
|
72
58
|
...callbacks.settings,
|
|
73
59
|
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
60
|
this.closeChat();
|
|
77
61
|
this.#report.close();
|
|
78
62
|
callbacks.settings?.onBeforeOpen?.();
|
|
79
63
|
},
|
|
80
64
|
});
|
|
81
65
|
}
|
|
82
|
-
/** Markup for the dock wrapper (chat panel + morphing HUD shell). */
|
|
83
66
|
static dockHtml(actStripHtml, bannerHtml, logAttr, flowsHtml, footHtml) {
|
|
84
67
|
const annotate = hiToggleIconHtml(PresenterIcon.ANNOTATE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
85
68
|
const chart = hiToggleIconHtml(PresenterIcon.CHART, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
86
69
|
const gear = hiToggleIconHtml(PresenterIcon.GEAR, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
87
70
|
const exit = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
88
71
|
return `<div ${DOCK_ATTR}>
|
|
89
|
-
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="
|
|
72
|
+
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="region" aria-label="Reticle session" aria-hidden="true">
|
|
90
73
|
<div class="reticle-chat-head">
|
|
91
74
|
<span class="reticle-chat-brand">${MARK_SVG}<span class="reticle-chat-brandname">${BRAND_NAME}</span></span>
|
|
75
|
+
<span ${TOOLBAR_ACCOUNT_ATTR} class="reticle-head-account"></span>
|
|
92
76
|
</div>
|
|
93
77
|
<button type="button" ${CHAT_MIN_ATTR} class="reticle-chat-min" title="${CHAT_MIN_LABEL}" aria-label="${CHAT_MIN_LABEL}">${hiIconHtml(PresenterIcon.CARET_DOWN, PRESENTER_ICON_SIZE.TOOLBAR)}</button>
|
|
94
78
|
${actStripHtml}
|
|
@@ -134,11 +118,9 @@ export class HudShell {
|
|
|
134
118
|
</div>
|
|
135
119
|
</div>`;
|
|
136
120
|
}
|
|
137
|
-
/** The impact report, so the presenter can feed it and the chat can open it. */
|
|
138
121
|
get report() {
|
|
139
122
|
return this.#report;
|
|
140
123
|
}
|
|
141
|
-
/** Light exactly the toolbar buttons whose panels are open. */
|
|
142
124
|
#syncToolbarToggles() {
|
|
143
125
|
const root = this.#root;
|
|
144
126
|
if (root === undefined)
|
|
@@ -152,11 +134,9 @@ export class HudShell {
|
|
|
152
134
|
lit(SETTINGS_BTN_ATTR, '1' === root.getAttribute(SETTINGS_ATTR));
|
|
153
135
|
lit(REPORT_BTN_ATTR, '1' === root.getAttribute(REPORT_ATTR));
|
|
154
136
|
}
|
|
155
|
-
/** Does the user currently want to annotate? */
|
|
156
137
|
isAnnotateOn() {
|
|
157
138
|
return this.#annotateOn;
|
|
158
139
|
}
|
|
159
|
-
/** Set the toggle and reflect it on the button, without firing the callback. */
|
|
160
140
|
setAnnotateOn(on) {
|
|
161
141
|
this.#annotateOn = on;
|
|
162
142
|
this.#annotateBtn?.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
@@ -200,10 +180,6 @@ export class HudShell {
|
|
|
200
180
|
root.removeAttribute(CHAT_ATTR);
|
|
201
181
|
this.#settings.mount(root);
|
|
202
182
|
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
183
|
this.#toggleSync = new MutationObserver(() => this.#syncToolbarToggles());
|
|
208
184
|
this.#toggleSync.observe(root, {
|
|
209
185
|
attributes: true,
|
|
@@ -247,15 +223,17 @@ export class HudShell {
|
|
|
247
223
|
}
|
|
248
224
|
document.addEventListener('pointerdown', this.#onDocPointerDown, { signal });
|
|
249
225
|
document.addEventListener('keydown', this.#onKeyDown, { signal });
|
|
226
|
+
this.#accountTeardown = mountAccountControl(root);
|
|
227
|
+
if (this.#pushedAccount !== undefined) {
|
|
228
|
+
const pushed = this.#pushedAccount;
|
|
229
|
+
this.paintAccount(pushed.account, pushed.dashboardUrl, pushed.details);
|
|
230
|
+
}
|
|
250
231
|
}
|
|
251
232
|
teardown() {
|
|
252
|
-
|
|
253
|
-
|
|
233
|
+
this.#accountTeardown?.();
|
|
234
|
+
this.#accountTeardown = undefined;
|
|
254
235
|
this.#listeners?.abort();
|
|
255
236
|
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
237
|
this.#toggleSync?.disconnect();
|
|
260
238
|
this.#toggleSync = undefined;
|
|
261
239
|
this.#dragTeardown?.();
|
|
@@ -286,12 +264,6 @@ export class HudShell {
|
|
|
286
264
|
if (this.#fab !== undefined)
|
|
287
265
|
this.#fab.setAttribute('aria-expanded', 'true');
|
|
288
266
|
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
267
|
this.openChat();
|
|
296
268
|
if (this.#dock !== undefined)
|
|
297
269
|
scheduleSyncDockLayout(this.#dock, this.#root);
|
|
@@ -316,8 +288,6 @@ export class HudShell {
|
|
|
316
288
|
if (this.isChatOpen())
|
|
317
289
|
return;
|
|
318
290
|
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
291
|
const log = this.#root.querySelector('[data-reticle-log]');
|
|
322
292
|
if (log !== null)
|
|
323
293
|
settleLogAtLatest(log);
|
|
@@ -327,10 +297,6 @@ export class HudShell {
|
|
|
327
297
|
this.#callbacks.onChatOpen?.();
|
|
328
298
|
if (this.#dock !== undefined)
|
|
329
299
|
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
300
|
}
|
|
335
301
|
closeChat() {
|
|
336
302
|
if (this.#root === undefined || !this.isChatOpen())
|
|
@@ -349,18 +315,10 @@ export class HudShell {
|
|
|
349
315
|
else
|
|
350
316
|
this.showChat();
|
|
351
317
|
}
|
|
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
318
|
showChat() {
|
|
360
319
|
this.#report.close();
|
|
361
320
|
this.openChat();
|
|
362
321
|
}
|
|
363
|
-
/** Pulse the FAB when new activity arrives while collapsed. */
|
|
364
322
|
pulseFab(active) {
|
|
365
323
|
this.#fab?.setAttribute('data-pulse', active ? '1' : '0');
|
|
366
324
|
}
|
|
@@ -370,15 +328,6 @@ export class HudShell {
|
|
|
370
328
|
this.#transitionLock = false;
|
|
371
329
|
}, TRANSITION_LOCK_MS);
|
|
372
330
|
}
|
|
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
331
|
#onDocPointerDown = (e) => {
|
|
383
332
|
if (this.#root === undefined || this.#dock === undefined)
|
|
384
333
|
return;
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
export declare const Z_OVERLAY = 2147483600;
|
|
1
|
+
import { Z_OVERLAY } from './chrome/layers.js';
|
|
2
|
+
export { Z_OVERLAY };
|
|
11
3
|
export declare const PRESENTER_CSS: string;
|