@reticlehq/browser 3.4.0 → 3.6.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.js +44 -43
- package/dist/actions/actions-press.d.ts +10 -4
- package/dist/actions/actions-press.js +108 -17
- package/dist/actions/actions.d.ts +2 -1
- package/dist/actions/actions.js +25 -26
- package/dist/actions/danger-context.js +1 -1
- package/dist/commands/commands.js +2 -6
- package/dist/connect-options.d.ts +1 -0
- package/dist/dom/a11y.js +43 -11
- package/dist/dom/addressing/refs.js +2 -1
- package/dist/dom/addressing/testid-attr.d.ts +4 -0
- package/dist/dom/addressing/testid-attr.js +14 -0
- package/dist/dom/occlusion.js +5 -1
- package/dist/dom/query.d.ts +1 -0
- package/dist/dom/query.js +42 -15
- package/dist/dom/snapshot.js +1 -0
- package/dist/observers/departure.js +51 -9
- package/dist/observers/dom.js +3 -2
- package/dist/observers/field.js +5 -3
- package/dist/observers/health.js +63 -2
- package/dist/observers/network-stream.d.ts +1 -1
- package/dist/observers/network-stream.js +3 -3
- package/dist/observers/network.js +1 -1
- package/dist/observers/storage.js +6 -1
- package/dist/presenter/carousel/carousel.d.ts +5 -2
- package/dist/presenter/carousel/carousel.js +34 -7
- package/dist/presenter/carousel/offer-card.d.ts +2 -2
- package/dist/presenter/carousel/offer-card.js +2 -1
- package/dist/presenter/carousel/panel-slides.d.ts +4 -3
- package/dist/presenter/carousel/panel-slides.js +43 -6
- package/dist/presenter/carousel/talk-card.d.ts +1 -1
- package/dist/presenter/chrome/log-kinds.d.ts +5 -0
- package/dist/presenter/chrome/log-kinds.js +1 -0
- package/dist/presenter/chrome/log-memory.d.ts +12 -0
- package/dist/presenter/chrome/log-memory.js +39 -0
- package/dist/presenter/chrome/presenter-hud-chrome.d.ts +1 -0
- package/dist/presenter/chrome/presenter-hud-chrome.js +7 -1
- package/dist/presenter/chrome/presenter-log.d.ts +5 -4
- package/dist/presenter/chrome/presenter-log.js +55 -5
- package/dist/presenter/chrome/presenter-report-copy.d.ts +11 -1
- package/dist/presenter/chrome/presenter-report-copy.js +14 -1
- package/dist/presenter/hud-telemetry.js +31 -2
- package/dist/presenter/icons/presenter-heroicons-data.d.ts +1 -0
- package/dist/presenter/icons/presenter-heroicons-data.js +4 -3
- package/dist/presenter/icons/presenter-icons.d.ts +2 -0
- package/dist/presenter/icons/presenter-icons.js +2 -0
- package/dist/presenter/presenter-account.d.ts +5 -4
- package/dist/presenter/presenter-account.js +23 -10
- package/dist/presenter/presenter-chat-views.d.ts +21 -0
- package/dist/presenter/presenter-chat-views.js +382 -0
- package/dist/presenter/presenter-config.d.ts +3 -2
- package/dist/presenter/presenter-config.js +4 -3
- package/dist/presenter/presenter-controls.d.ts +4 -2
- package/dist/presenter/presenter-controls.js +231 -51
- package/dist/presenter/presenter-design-tokens.d.ts +1 -0
- package/dist/presenter/presenter-design-tokens.js +34 -0
- package/dist/presenter/presenter-dock-layout.js +1 -1
- package/dist/presenter/presenter-frame.d.ts +12 -0
- package/dist/presenter/presenter-frame.js +189 -0
- package/dist/presenter/presenter-plan.d.ts +10 -0
- package/dist/presenter/presenter-plan.js +185 -0
- package/dist/presenter/presenter-report-styles.js +7 -0
- package/dist/presenter/presenter-report.d.ts +1 -1
- package/dist/presenter/presenter-report.js +53 -16
- package/dist/presenter/presenter-settings-styles.js +10 -0
- package/dist/presenter/presenter-settings.d.ts +5 -0
- package/dist/presenter/presenter-settings.js +71 -11
- package/dist/presenter/presenter-shell-styles.js +39 -42
- package/dist/presenter/presenter-shell.d.ts +8 -1
- package/dist/presenter/presenter-shell.js +124 -72
- package/dist/presenter/presenter-styles.js +9 -1
- package/dist/presenter/presenter.d.ts +4 -3
- package/dist/presenter/presenter.js +101 -13
- package/dist/presenter/tour/tour.d.ts +4 -1
- package/dist/presenter/tour/tour.js +6 -4
- package/dist/recorder/recorder.js +2 -2
- package/dist/registry/auto-testids.js +3 -4
- package/dist/registry/declared-platform.js +2 -0
- package/dist/reticle-inject.js +880 -513
- package/dist/reticle.d.ts +10 -1
- package/dist/reticle.js +73 -9
- package/dist/review/annotator-styles.d.ts +1 -1
- package/dist/review/annotator.d.ts +7 -0
- package/dist/review/annotator.js +20 -2
- package/dist/review/mark-anchor.js +2 -2
- package/dist/session-continuity.js +2 -1
- package/dist/storage-keys.d.ts +14 -0
- package/dist/storage-keys.js +17 -0
- package/package.json +3 -2
|
@@ -3,34 +3,53 @@ import { PresenterReport, reportPanelHtml } from './presenter-report.js';
|
|
|
3
3
|
import { paintToolbarAccount, TOOLBAR_ACCOUNT_ATTR } from './presenter-workspace.js';
|
|
4
4
|
import { mountAccountControl } from './presenter-account.js';
|
|
5
5
|
import { paintSettingsAccount } from './presenter-settings.js';
|
|
6
|
-
import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR,
|
|
6
|
+
import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, MINIMISED_STORAGE_KEY, } from './presenter-config.js';
|
|
7
7
|
import { offerDismissed } from './carousel/offer-card.js';
|
|
8
8
|
import { paintCarousel } from './carousel/carousel.js';
|
|
9
9
|
import { panelSlides } from './carousel/panel-slides.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { paintRail, RAIL_HTML, RAIL_PROMO_ATTR } from './presenter-frame.js';
|
|
11
|
+
import { FAB_TOGGLE_HTML, MARK_SVG } from './chrome/presenter-brand.js';
|
|
12
|
+
import { settleLogAtLatest } from './chrome/presenter-log.js';
|
|
12
13
|
import { installHudDragHandles, installHudPositionGuards } from './presenter-drag.js';
|
|
13
14
|
import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
14
15
|
import { hiIconHtml, hiToggleIconHtml, PRESENTER_ICON_SIZE, PresenterIcon, } from './icons/presenter-icons.js';
|
|
15
16
|
import { HUD_SURFACE_CLASS, HUD_LOG_WELL_CLASS } from './chrome/presenter-hud-chrome.js';
|
|
16
|
-
import {
|
|
17
|
+
import { ChatViews, CHAT_VIEWS_NAV_HTML, ANNOTATIONS_HTML, FLOWS_PAGE_HTML, platformBase, } from './presenter-chat-views.js';
|
|
17
18
|
import { PresenterSettingsPanel, settingsPanelHtml, } from './presenter-settings.js';
|
|
18
19
|
const DRAG_HANDLE_CLASS = 'reticle-toolbar-drag';
|
|
19
20
|
const TRANSITION_LOCK_MS = 120;
|
|
20
|
-
const ANNOTATE_LABEL = 'Annotate';
|
|
21
21
|
const CHAT_MIN_LABEL = 'Minimise chat';
|
|
22
22
|
const CHAT_PILL_LABEL = 'Open agent chat';
|
|
23
|
-
const REPORT_LABEL = 'Impact';
|
|
24
23
|
const SETTINGS_LABEL = 'Settings';
|
|
24
|
+
const AGENT_LOG_TITLE = 'Reticle';
|
|
25
25
|
const EXIT_LABEL = 'Exit';
|
|
26
|
+
function paintPromo(root, offer, notices = [], base) {
|
|
27
|
+
const target = root.querySelector(`[${RAIL_PROMO_ATTR}]`);
|
|
28
|
+
if (null === target)
|
|
29
|
+
return;
|
|
30
|
+
let dismissed = false;
|
|
31
|
+
try {
|
|
32
|
+
dismissed = offerDismissed(window.localStorage);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
}
|
|
36
|
+
let storage;
|
|
37
|
+
try {
|
|
38
|
+
storage = window.sessionStorage;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
storage = undefined;
|
|
42
|
+
}
|
|
43
|
+
paintCarousel(target, panelSlides(offer, dismissed, notices, base), storage);
|
|
44
|
+
}
|
|
26
45
|
export class HudShell {
|
|
27
46
|
#root;
|
|
28
47
|
#dock;
|
|
29
48
|
#fab;
|
|
30
49
|
#chatPanel;
|
|
31
|
-
#chatToggle;
|
|
32
50
|
#collapseBtn;
|
|
33
51
|
#settings;
|
|
52
|
+
#chatViews;
|
|
34
53
|
#dragTeardown;
|
|
35
54
|
#layoutTeardown;
|
|
36
55
|
#transitionLock = false;
|
|
@@ -48,9 +67,44 @@ export class HudShell {
|
|
|
48
67
|
});
|
|
49
68
|
#callbacks;
|
|
50
69
|
#pushedAccount;
|
|
70
|
+
#pushedOffer;
|
|
71
|
+
#pushedNotices = [];
|
|
72
|
+
#pushedHarness;
|
|
73
|
+
#promoBase;
|
|
51
74
|
#accountTeardown;
|
|
52
75
|
paintHarness(config) {
|
|
76
|
+
this.#pushedHarness = config;
|
|
53
77
|
this.#settings.paintHarness(config);
|
|
78
|
+
this.#chatViews.paintHarness(config);
|
|
79
|
+
this.#repaintPromoIfMoved();
|
|
80
|
+
}
|
|
81
|
+
#promoLinks() {
|
|
82
|
+
return platformBase(this.#pushedHarness, this.#pushedAccount?.account ?? { signedIn: false });
|
|
83
|
+
}
|
|
84
|
+
#repaintPromoIfMoved() {
|
|
85
|
+
const base = this.#promoLinks();
|
|
86
|
+
if (this.#root === undefined || base === this.#promoBase)
|
|
87
|
+
return;
|
|
88
|
+
this.#promoBase = base;
|
|
89
|
+
paintPromo(this.#root, this.#pushedOffer, this.#pushedNotices, base);
|
|
90
|
+
}
|
|
91
|
+
paintImpact(verdicts) {
|
|
92
|
+
this.#chatViews.paintImpact(verdicts);
|
|
93
|
+
}
|
|
94
|
+
paintAnnotations(items) {
|
|
95
|
+
this.#chatViews.paintAnnotations(items);
|
|
96
|
+
}
|
|
97
|
+
openView(view) {
|
|
98
|
+
if ('activity' === view)
|
|
99
|
+
this.showChat();
|
|
100
|
+
else {
|
|
101
|
+
if (this.isCollapsed())
|
|
102
|
+
this.expand();
|
|
103
|
+
this.closeChat();
|
|
104
|
+
this.#settings.close();
|
|
105
|
+
this.#report.close();
|
|
106
|
+
}
|
|
107
|
+
this.#chatViews.open(view);
|
|
54
108
|
}
|
|
55
109
|
paintAccount(account, dashboardUrl, details = {}) {
|
|
56
110
|
this.#pushedAccount = { account, dashboardUrl, details };
|
|
@@ -58,65 +112,66 @@ export class HudShell {
|
|
|
58
112
|
return;
|
|
59
113
|
paintToolbarAccount(this.#root, account, dashboardUrl, details);
|
|
60
114
|
paintSettingsAccount(this.#root, account, dashboardUrl, details);
|
|
115
|
+
paintRail(this.#root, account);
|
|
116
|
+
this.#chatViews.paintAccount(account);
|
|
117
|
+
this.#repaintPromoIfMoved();
|
|
61
118
|
}
|
|
62
|
-
|
|
63
|
-
paintOffer(offer) {
|
|
119
|
+
paintOffer(offer, notices = []) {
|
|
64
120
|
this.#pushedOffer = offer;
|
|
65
|
-
this.#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!(log instanceof HTMLElement))
|
|
70
|
-
return;
|
|
71
|
-
const declined = offerDismissed(this.#storage());
|
|
72
|
-
paintCarousel(log, panelSlides(this.#pushedOffer, declined), this.#sessionStorage());
|
|
73
|
-
}
|
|
74
|
-
#sessionStorage() {
|
|
75
|
-
try {
|
|
76
|
-
return globalThis.sessionStorage;
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return undefined;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
#storage() {
|
|
83
|
-
try {
|
|
84
|
-
return globalThis.localStorage;
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
121
|
+
this.#pushedNotices = notices;
|
|
122
|
+
this.#promoBase = this.#promoLinks();
|
|
123
|
+
if (this.#root !== undefined)
|
|
124
|
+
paintPromo(this.#root, offer, notices, this.#promoBase);
|
|
89
125
|
}
|
|
90
126
|
constructor(callbacks = {}) {
|
|
91
127
|
this.#callbacks = callbacks;
|
|
128
|
+
this.#chatViews = new ChatViews((enabled) => callbacks.onHarness?.(enabled), () => {
|
|
129
|
+
this.#chatViews.closePage();
|
|
130
|
+
this.closeChat();
|
|
131
|
+
this.#report.open();
|
|
132
|
+
}, (view) => {
|
|
133
|
+
if ('activity' === view) {
|
|
134
|
+
this.#chatViews.open(view);
|
|
135
|
+
this.showChat();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (this.isCollapsed())
|
|
139
|
+
this.expand();
|
|
140
|
+
this.closeChat();
|
|
141
|
+
this.#settings.close();
|
|
142
|
+
this.#report.close();
|
|
143
|
+
});
|
|
92
144
|
this.#settings = new PresenterSettingsPanel({
|
|
93
145
|
...callbacks.settings,
|
|
94
146
|
onBeforeOpen: () => {
|
|
95
147
|
this.closeChat();
|
|
148
|
+
this.#chatViews.closePage();
|
|
96
149
|
this.#report.close();
|
|
97
150
|
callbacks.settings?.onBeforeOpen?.();
|
|
98
151
|
},
|
|
99
152
|
});
|
|
100
153
|
}
|
|
101
154
|
static dockHtml(actStripHtml, bannerHtml, logAttr, flowsHtml, footHtml) {
|
|
102
|
-
const annotate = hiToggleIconHtml(PresenterIcon.ANNOTATE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
103
|
-
const chart = hiToggleIconHtml(PresenterIcon.CHART, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
104
155
|
const gear = hiToggleIconHtml(PresenterIcon.GEAR, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
105
156
|
const exit = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
106
|
-
return `<div ${DOCK_ATTR}>
|
|
107
|
-
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="region" aria-label="
|
|
157
|
+
return `<div ${DOCK_ATTR} role="complementary" aria-label="Reticle">
|
|
158
|
+
<div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="region" aria-label="Agent Log" aria-hidden="true">
|
|
108
159
|
<div class="reticle-chat-head">
|
|
109
|
-
<span class="reticle-chat-brand">${MARK_SVG}<span class="reticle-chat-brandname">${
|
|
160
|
+
<span class="reticle-chat-brand">${MARK_SVG}<span class="reticle-chat-brandname">${AGENT_LOG_TITLE}</span></span>
|
|
110
161
|
<span ${TOOLBAR_ACCOUNT_ATTR} class="reticle-head-account"></span>
|
|
111
162
|
</div>
|
|
112
163
|
<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>
|
|
113
164
|
${actStripHtml}
|
|
114
165
|
<span class="reticle-tally" data-reticle-tally hidden></span>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
166
|
+
<section class="reticle-chat-view" role="region" aria-label="Agent Log">
|
|
167
|
+
${bannerHtml}
|
|
168
|
+
<div class="${HUD_LOG_WELL_CLASS}"><div ${logAttr}></div></div>
|
|
169
|
+
${flowsHtml}
|
|
170
|
+
</section>
|
|
118
171
|
${footHtml}
|
|
119
172
|
</div>
|
|
173
|
+
${FLOWS_PAGE_HTML}
|
|
174
|
+
${ANNOTATIONS_HTML}
|
|
120
175
|
<button type="button" ${CHAT_PILL_ATTR} class="reticle-chat-pill" title="${CHAT_PILL_LABEL}" aria-label="${CHAT_PILL_LABEL}">
|
|
121
176
|
${MARK_SVG}
|
|
122
177
|
<span class="reticle-chat-pill-text" data-reticle-chat-pill-text></span>
|
|
@@ -125,21 +180,13 @@ export class HudShell {
|
|
|
125
180
|
</button>
|
|
126
181
|
${settingsPanelHtml()}
|
|
127
182
|
${reportPanelHtml()}
|
|
183
|
+
${RAIL_HTML}
|
|
128
184
|
<div data-reticle-hud>
|
|
129
185
|
<div class="reticle-hud-deco" aria-hidden="true"></div>
|
|
130
186
|
${FAB_TOGGLE_HTML}
|
|
131
187
|
<div class="reticle-toolbar ${DRAG_HANDLE_CLASS}" role="toolbar" aria-label="Reticle controls">
|
|
132
|
-
<div class="reticle-toolbar-actions">${CONTROLS_TOOLBAR_HTML}</div>
|
|
133
|
-
<span class="reticle-tb-sep" aria-hidden="true"></span>
|
|
134
188
|
<div class="reticle-toolbar-chrome">
|
|
135
|
-
|
|
136
|
-
<button type="button" ${ANNOTATE_BTN_ATTR} class="reticle-tb-btn reticle-tb-btn--toggle" title="${ANNOTATE_LABEL}" aria-label="${ANNOTATE_LABEL}" aria-pressed="false" data-active="0">${annotate}</button>
|
|
137
|
-
<span class="reticle-tb-tip">${ANNOTATE_LABEL}</span>
|
|
138
|
-
</div>
|
|
139
|
-
<div class="reticle-tb-wrap">
|
|
140
|
-
<button type="button" ${REPORT_BTN_ATTR} class="reticle-tb-btn reticle-tb-btn--toggle" title="${REPORT_LABEL}" aria-label="${REPORT_LABEL}" aria-pressed="false" data-active="0">${chart}</button>
|
|
141
|
-
<span class="reticle-tb-tip">${REPORT_LABEL}</span>
|
|
142
|
-
</div>
|
|
189
|
+
${CHAT_VIEWS_NAV_HTML}
|
|
143
190
|
<div class="reticle-tb-wrap">
|
|
144
191
|
<button type="button" ${SETTINGS_BTN_ATTR} class="reticle-tb-btn reticle-tb-btn--toggle" title="${SETTINGS_LABEL}" aria-label="${SETTINGS_LABEL}" aria-pressed="false" data-active="0">${gear}</button>
|
|
145
192
|
<span class="reticle-tb-tip">${SETTINGS_LABEL}</span>
|
|
@@ -167,7 +214,15 @@ export class HudShell {
|
|
|
167
214
|
};
|
|
168
215
|
lit(CHAT_TOGGLE_ATTR, '1' === root.getAttribute(CHAT_ATTR));
|
|
169
216
|
lit(SETTINGS_BTN_ATTR, '1' === root.getAttribute(SETTINGS_ATTR));
|
|
170
|
-
|
|
217
|
+
const impact = root.querySelector('[data-reticle-chat-impact]');
|
|
218
|
+
if (impact !== null) {
|
|
219
|
+
const on = '1' === root.getAttribute(REPORT_ATTR);
|
|
220
|
+
impact.setAttribute('data-active', on ? '1' : '0');
|
|
221
|
+
if (on)
|
|
222
|
+
impact.setAttribute('aria-current', 'page');
|
|
223
|
+
else
|
|
224
|
+
impact.removeAttribute('aria-current');
|
|
225
|
+
}
|
|
171
226
|
}
|
|
172
227
|
isAnnotateOn() {
|
|
173
228
|
return this.#annotateOn;
|
|
@@ -176,6 +231,14 @@ export class HudShell {
|
|
|
176
231
|
this.#annotateOn = on;
|
|
177
232
|
this.#annotateBtn?.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
178
233
|
this.#annotateBtn?.setAttribute('data-active', on ? '1' : '0');
|
|
234
|
+
this.#annotateBtn?.setAttribute('aria-label', on ? 'Stop adding notes' : 'Add notes');
|
|
235
|
+
this.#annotateBtn?.setAttribute('title', on ? 'Stop adding notes' : 'Add notes');
|
|
236
|
+
const label = this.#annotateBtn?.querySelector('[data-reticle-notes-toggle-label]');
|
|
237
|
+
if (label !== null && label !== undefined)
|
|
238
|
+
label.textContent = on ? 'Stop adding notes' : 'Add notes';
|
|
239
|
+
this.#root
|
|
240
|
+
?.querySelector('[data-reticle-chat-view-btn="annotations"]')
|
|
241
|
+
?.setAttribute('data-capture', on ? '1' : '0');
|
|
179
242
|
}
|
|
180
243
|
mount(root) {
|
|
181
244
|
this.#listeners = new AbortController();
|
|
@@ -186,10 +249,9 @@ export class HudShell {
|
|
|
186
249
|
this.#fab = fabEl instanceof HTMLButtonElement ? fabEl : undefined;
|
|
187
250
|
const chatPanelEl = root.querySelector(`[${CHAT_PANEL_ATTR}]`);
|
|
188
251
|
this.#chatPanel = chatPanelEl instanceof HTMLElement ? chatPanelEl : undefined;
|
|
189
|
-
const chatToggleEl = root.querySelector(`[${CHAT_TOGGLE_ATTR}]`);
|
|
190
|
-
this.#chatToggle = chatToggleEl instanceof HTMLElement ? chatToggleEl : undefined;
|
|
191
252
|
const annotateEl = root.querySelector(`[${ANNOTATE_BTN_ATTR}]`);
|
|
192
253
|
this.#annotateBtn = annotateEl instanceof HTMLButtonElement ? annotateEl : undefined;
|
|
254
|
+
this.setAnnotateOn(this.#annotateOn);
|
|
193
255
|
this.#annotateBtn?.addEventListener('click', (e) => {
|
|
194
256
|
e.preventDefault();
|
|
195
257
|
e.stopPropagation();
|
|
@@ -215,17 +277,15 @@ export class HudShell {
|
|
|
215
277
|
root.removeAttribute(CHAT_ATTR);
|
|
216
278
|
this.#settings.mount(root);
|
|
217
279
|
this.#report.mount(root);
|
|
280
|
+
this.#chatViews.mount(root);
|
|
281
|
+
this.#promoBase = this.#promoLinks();
|
|
282
|
+
paintPromo(root, this.#pushedOffer, this.#pushedNotices, this.#promoBase);
|
|
218
283
|
this.#toggleSync = new MutationObserver(() => this.#syncToolbarToggles());
|
|
219
284
|
this.#toggleSync.observe(root, {
|
|
220
285
|
attributes: true,
|
|
221
286
|
attributeFilter: [CHAT_ATTR, SETTINGS_ATTR, REPORT_ATTR],
|
|
222
287
|
});
|
|
223
288
|
this.#syncToolbarToggles();
|
|
224
|
-
root.querySelector(`[${REPORT_BTN_ATTR}]`)?.addEventListener('click', (e) => {
|
|
225
|
-
e.preventDefault();
|
|
226
|
-
e.stopPropagation();
|
|
227
|
-
this.#report.toggle();
|
|
228
|
-
}, { signal });
|
|
229
289
|
this.#fab?.addEventListener('click', (e) => {
|
|
230
290
|
e.stopPropagation();
|
|
231
291
|
if (this.#suppressFabClick) {
|
|
@@ -238,10 +298,6 @@ export class HudShell {
|
|
|
238
298
|
e.stopPropagation();
|
|
239
299
|
this.collapse();
|
|
240
300
|
}, { signal });
|
|
241
|
-
this.#chatToggle?.addEventListener('click', (e) => {
|
|
242
|
-
e.stopPropagation();
|
|
243
|
-
this.toggleChat();
|
|
244
|
-
}, { signal });
|
|
245
301
|
const toolbarDrag = root.querySelector(`.${DRAG_HANDLE_CLASS}`);
|
|
246
302
|
const dragHandles = [this.#fab, toolbarDrag].filter((el) => el instanceof HTMLElement);
|
|
247
303
|
if (this.#dock !== undefined && dragHandles.length > 0) {
|
|
@@ -250,20 +306,18 @@ export class HudShell {
|
|
|
250
306
|
this.#suppressFabClick = true;
|
|
251
307
|
},
|
|
252
308
|
onDragEnd: (moved) => {
|
|
253
|
-
|
|
254
|
-
this.#suppressFabClick = true;
|
|
309
|
+
this.#suppressFabClick = moved && this.isCollapsed();
|
|
255
310
|
},
|
|
256
311
|
});
|
|
257
312
|
this.#layoutTeardown = installHudPositionGuards(this.#dock, root);
|
|
258
313
|
}
|
|
259
314
|
document.addEventListener('pointerdown', this.#onDocPointerDown, { signal });
|
|
260
315
|
document.addEventListener('keydown', this.#onKeyDown, { signal });
|
|
261
|
-
this.#accountTeardown = mountAccountControl(root);
|
|
316
|
+
this.#accountTeardown = mountAccountControl(root, () => this.#callbacks.onSignIn?.());
|
|
262
317
|
if (this.#pushedAccount !== undefined) {
|
|
263
318
|
const pushed = this.#pushedAccount;
|
|
264
319
|
this.paintAccount(pushed.account, pushed.dashboardUrl, pushed.details);
|
|
265
320
|
}
|
|
266
|
-
this.#paintCarousel();
|
|
267
321
|
}
|
|
268
322
|
teardown() {
|
|
269
323
|
this.#accountTeardown?.();
|
|
@@ -277,11 +331,11 @@ export class HudShell {
|
|
|
277
331
|
this.#layoutTeardown?.();
|
|
278
332
|
this.#layoutTeardown = undefined;
|
|
279
333
|
this.#settings.teardown();
|
|
334
|
+
this.#chatViews.teardown();
|
|
280
335
|
this.#root = undefined;
|
|
281
336
|
this.#dock = undefined;
|
|
282
337
|
this.#fab = undefined;
|
|
283
338
|
this.#chatPanel = undefined;
|
|
284
|
-
this.#chatToggle = undefined;
|
|
285
339
|
this.#collapseBtn = undefined;
|
|
286
340
|
}
|
|
287
341
|
isCollapsed() {
|
|
@@ -323,6 +377,8 @@ export class HudShell {
|
|
|
323
377
|
if (this.isCollapsed())
|
|
324
378
|
this.expand();
|
|
325
379
|
this.#settings.close();
|
|
380
|
+
this.#chatViews.closePage();
|
|
381
|
+
this.#chatViews.open('activity');
|
|
326
382
|
if (this.isChatOpen())
|
|
327
383
|
return;
|
|
328
384
|
this.#root.setAttribute(CHAT_ATTR, '1');
|
|
@@ -330,8 +386,6 @@ export class HudShell {
|
|
|
330
386
|
if (log !== null)
|
|
331
387
|
settleLogAtLatest(log);
|
|
332
388
|
this.#chatPanel?.setAttribute('aria-hidden', 'false');
|
|
333
|
-
this.#chatToggle?.setAttribute('data-active', '1');
|
|
334
|
-
this.#chatToggle?.setAttribute('aria-pressed', 'true');
|
|
335
389
|
this.#callbacks.onChatOpen?.();
|
|
336
390
|
if (this.#dock !== undefined)
|
|
337
391
|
scheduleSyncDockLayout(this.#dock, this.#root);
|
|
@@ -341,8 +395,6 @@ export class HudShell {
|
|
|
341
395
|
return;
|
|
342
396
|
this.#root.removeAttribute(CHAT_ATTR);
|
|
343
397
|
this.#chatPanel?.setAttribute('aria-hidden', 'true');
|
|
344
|
-
this.#chatToggle?.setAttribute('data-active', '0');
|
|
345
|
-
this.#chatToggle?.setAttribute('aria-pressed', 'false');
|
|
346
398
|
this.#callbacks.onChatClose?.();
|
|
347
399
|
if (this.#dock !== undefined)
|
|
348
400
|
scheduleSyncDockLayout(this.#dock, this.#root);
|
|
@@ -9,8 +9,13 @@ import { REPORT_CSS } from './presenter-report-styles.js';
|
|
|
9
9
|
import { OFFER_CSS } from './carousel/offer-card.js';
|
|
10
10
|
import { TALK_CSS } from './carousel/talk-card.js';
|
|
11
11
|
import { CAROUSEL_CSS } from './carousel/carousel.js';
|
|
12
|
+
import { CHAT_VIEWS_CSS } from './presenter-chat-views.js';
|
|
13
|
+
import { PLAN_CSS } from './presenter-plan.js';
|
|
14
|
+
import { FRAME_CSS } from './presenter-frame.js';
|
|
15
|
+
import { PRESENTER_DESIGN_TOKENS_CSS } from './presenter-design-tokens.js';
|
|
12
16
|
export { Z_OVERLAY };
|
|
13
17
|
export const PRESENTER_CSS = `
|
|
18
|
+
${PRESENTER_DESIGN_TOKENS_CSS}
|
|
14
19
|
[data-reticle-overlay]{position:fixed;inset:0;pointer-events:none;z-index:${String(Z_OVERLAY)};}
|
|
15
20
|
/**
|
|
16
21
|
* The session glow: the page itself says an agent is here, and BREATHES while it is working.
|
|
@@ -70,4 +75,7 @@ ${OFFER_CSS}
|
|
|
70
75
|
${TALK_CSS}
|
|
71
76
|
${CAROUSEL_CSS}
|
|
72
77
|
${LOG_CSS}
|
|
73
|
-
${
|
|
78
|
+
${CHAT_VIEWS_CSS}
|
|
79
|
+
${PLAN_CSS}
|
|
80
|
+
${CONTROLS_CSS}
|
|
81
|
+
${FRAME_CSS}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PresenterMode, SessionState, type PresenterTone } from '@reticlehq/core';
|
|
2
|
-
import { type LogKind, type LogResult, type LogHandle } from './chrome/presenter-log.js';
|
|
1
|
+
import { HudCorner, HudVisibility, PresenterMode, SessionState, type PresenterTone } from '@reticlehq/core';
|
|
2
|
+
import { type LogActor, type LogKind, type LogResult, type LogHandle } from './chrome/presenter-log.js';
|
|
3
3
|
import { type PresenterOptions } from './presenter-config.js';
|
|
4
4
|
import { type PresenterRunState } from './presenter-run-state.js';
|
|
5
5
|
import { type ControlHandler } from './presenter-controls.js';
|
|
@@ -35,9 +35,10 @@ export declare class Presenter {
|
|
|
35
35
|
get mode(): PresenterMode;
|
|
36
36
|
setMode(mode: PresenterMode): void;
|
|
37
37
|
status(text: string): void;
|
|
38
|
+
placeHud(visibility: HudVisibility | undefined, corner: HudCorner | undefined): string[];
|
|
38
39
|
setIdleEndMs(ms: number): void;
|
|
39
40
|
runState(): PresenterRunState | Record<string, unknown>;
|
|
40
|
-
log(kind: LogKind, text: string, result?: LogResult): LogHandle | undefined;
|
|
41
|
+
log(kind: LogKind, text: string, result?: LogResult, actor?: LogActor): LogHandle | undefined;
|
|
41
42
|
narrate(text: string, level?: string): LogHandle | undefined;
|
|
42
43
|
setThrottled(throttled: boolean): void;
|
|
43
44
|
beforeAct(refId: string, action: string, label: string): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionType, HumanControlKind, ReticleCommand, PresenterMode, SessionState, isPresenterTone, isSessionState, } from '@reticlehq/core';
|
|
1
|
+
import { ActionType, HudCorner, HudVisibility, HumanControlKind, ReticleCommand, PresenterMode, SessionState, isPresenterTone, isSessionState, } from '@reticlehq/core';
|
|
2
2
|
import { refs } from '../dom/addressing/refs.js';
|
|
3
3
|
import { unreachableStripText } from '../transport/unreachable-message.js';
|
|
4
4
|
import { actionVerb } from './chrome/presenter-verbs.js';
|
|
@@ -7,17 +7,21 @@ import { LOG_KIND, CHIP_LABEL, DATA_RETICLE_LOG, clampLogMax, formatElapsed, hum
|
|
|
7
7
|
import { PRESENTER_CSS } from './presenter-styles.js';
|
|
8
8
|
import { HudShell } from './presenter-shell.js';
|
|
9
9
|
import { parseImpactSnapshot } from './chrome/presenter-report-copy.js';
|
|
10
|
-
import {
|
|
10
|
+
import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
11
|
+
import { applyHudPosition, clampHudPosition, hudLayoutBox, resetHudDockPosition, } from './presenter-hud-position.js';
|
|
12
|
+
import { BorderMode, DEFAULT_BORDER_MODE, DOCK_ATTR, HIDDEN_UNTIL_RESTART_ATTR, DATA_BUSY, BUSY_OFF, effectivePaceMs, IDLE_AFTER_MS, HEARTBEAT_MS, IDLE_NOTICE_MS, IDLE_END_MS, IDLE_END_MIN_MS, ACT_STRIP, STATE_ATTR, UNREACHABLE_STATE, GLOW_FADE_MS, GLOW_ON, GLOW_OFF, DATA_ON, THROTTLED_ATTR, LIVENESS_ATTR, MARKERS_BTN_ATTR, CLEAR_MARKS_ATTR, COPY_MARKS_ATTR, MARKS_ROW_ATTR, MARK_COUNT_ATTR, } from './presenter-config.js';
|
|
11
13
|
import { buildRunState } from './presenter-run-state.js';
|
|
12
14
|
import { moveCursor, ringAround, spawnRipple, pace } from './chrome/presenter-effects.js';
|
|
13
15
|
import { GlowController } from './presenter-glow.js';
|
|
14
16
|
import { PresenterIcon, PRESENTER_ICON_SIZE, hiIcon } from './icons/presenter-icons.js';
|
|
15
17
|
import { renderTally } from './chrome/presenter-tally.js';
|
|
16
|
-
import { CONTROLS_BANNER_HTML, CONTROLS_FLOWS_HTML, CONTROLS_MARKS_HTML, CONTROLS_FOOT_HTML, ENDED_FADE_MS, ControlPanel, } from './presenter-controls.js';
|
|
18
|
+
import { CONTROLS_BANNER_HTML, CONTROLS_FLOWS_HTML, CONTROLS_MARKS_HTML, CONTROLS_FOOT_HTML, CONTROLS_STATUS_HTML, ENDED_FADE_MS, ControlPanel, } from './presenter-controls.js';
|
|
17
19
|
import { statusTheme, blockerHtml, getPresenterSettings, OutputDetail, syncPageBlocker, } from './presenter-settings.js';
|
|
18
20
|
import { Annotator } from '../review/annotator.js';
|
|
19
21
|
import { shouldAutoOpenChat } from './presenter-shell.js';
|
|
20
22
|
import { installHudTelemetry } from './hud-telemetry.js';
|
|
23
|
+
import { PLAN_HTML, PlanBoard, parsePlanView } from './presenter-plan.js';
|
|
24
|
+
import { claimLog, readRememberedLog, rememberLog, } from './chrome/log-memory.js';
|
|
21
25
|
const COPIED_FLASH_MS = 1600;
|
|
22
26
|
export { GlowPhase } from './presenter-config.js';
|
|
23
27
|
export { LOG_KIND, LOG_RESULT } from './chrome/presenter-log.js';
|
|
@@ -51,6 +55,8 @@ export class Presenter {
|
|
|
51
55
|
#sessionActive = false;
|
|
52
56
|
#logMax;
|
|
53
57
|
#log;
|
|
58
|
+
#plan = new PlanBoard();
|
|
59
|
+
#remembered = [];
|
|
54
60
|
#logBaseMs;
|
|
55
61
|
#onControl;
|
|
56
62
|
#onHudUse;
|
|
@@ -92,12 +98,15 @@ export class Presenter {
|
|
|
92
98
|
onAnnotateToggle: () => this.#syncAnnotator(),
|
|
93
99
|
onCollapse: () => this.#syncAnnotator(),
|
|
94
100
|
onSyncNow: () => this.#onControl?.({ kind: HumanControlKind.SYNC }),
|
|
101
|
+
onSignIn: () => this.#onControl?.({ kind: HumanControlKind.SIGNIN }),
|
|
102
|
+
onHarness: (enabled) => this.#onControl?.({ kind: HumanControlKind.HARNESS, text: enabled ? 'on' : 'off' }),
|
|
95
103
|
settings: {
|
|
96
104
|
onBeforeOpen: () => {
|
|
97
105
|
if (this.#shell.isCollapsed())
|
|
98
106
|
this.#shell.expand();
|
|
99
107
|
},
|
|
100
108
|
onHideUntilRestart: () => this.#applyHideUntilRestart(),
|
|
109
|
+
onKill: () => options.onKill?.(),
|
|
101
110
|
onSettingsChange: (s) => this.#onSettingsChange(s),
|
|
102
111
|
onHarness: (enabled) => this.#onControl?.({ kind: HumanControlKind.HARNESS, text: enabled ? 'on' : 'off' }),
|
|
103
112
|
},
|
|
@@ -122,12 +131,24 @@ export class Presenter {
|
|
|
122
131
|
const a = command.args;
|
|
123
132
|
if (command.name === ReticleCommand.FLOWS)
|
|
124
133
|
return void this.#panel.setFlows(a['flows']);
|
|
134
|
+
if (command.name === ReticleCommand.FLOW_PROGRESS)
|
|
135
|
+
return void this.#panel.setFlowProgress(a);
|
|
136
|
+
if (command.name === ReticleCommand.PLAN) {
|
|
137
|
+
const view = parsePlanView(a);
|
|
138
|
+
if (view !== undefined)
|
|
139
|
+
this.#plan.paint(view);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
125
142
|
if (command.name === ReticleCommand.IMPACT) {
|
|
126
143
|
const snapshot = parseImpactSnapshot(a['snapshot']);
|
|
127
144
|
if (snapshot !== undefined) {
|
|
128
145
|
this.#shell.report.setSnapshot(snapshot);
|
|
129
|
-
this.#shell.paintOffer(snapshot.harnessOffer);
|
|
146
|
+
this.#shell.paintOffer(snapshot.harnessOffer, snapshot.notices);
|
|
130
147
|
this.#shell.paintHarness(snapshot.harnessConfig);
|
|
148
|
+
this.#shell.paintImpact(snapshot.project.counts.verdicts);
|
|
149
|
+
const owner = true === snapshot.account?.signedIn ? snapshot.account.email : undefined;
|
|
150
|
+
if (claimLog(owner))
|
|
151
|
+
this.#clearRunLog();
|
|
131
152
|
this.#shell.paintAccount(snapshot.account, snapshot.dashboardUrl, {
|
|
132
153
|
projectName: snapshot.projectName,
|
|
133
154
|
dashboardUrl: snapshot.dashboardUrl,
|
|
@@ -159,13 +180,13 @@ export class Presenter {
|
|
|
159
180
|
document.head.appendChild(style);
|
|
160
181
|
const root = document.createElement('div');
|
|
161
182
|
root.setAttribute('data-reticle-overlay', '');
|
|
162
|
-
const actStrip = `<div class="reticle-act-strip" data-liveness="idle"><span class="reticle-act-dot" aria-hidden="true"></span><span class="reticle-act">${ACT_STRIP.READY}</span
|
|
183
|
+
const actStrip = `<div class="reticle-act-strip" data-liveness="idle"><span class="reticle-act-dot" aria-hidden="true"></span><span class="reticle-act">${ACT_STRIP.READY}</span>${CONTROLS_BANNER_HTML}<span class="reticle-chip" data-reticle-chip></span><div class="reticle-act-actions">${CONTROLS_STATUS_HTML}</div></div>`;
|
|
163
184
|
root.innerHTML = `
|
|
164
185
|
${blockerHtml()}
|
|
165
186
|
<div data-reticle-glow></div>
|
|
166
187
|
<div data-reticle-cursor></div>
|
|
167
188
|
<div data-reticle-ring></div>
|
|
168
|
-
${HudShell.dockHtml(actStrip,
|
|
189
|
+
${HudShell.dockHtml(actStrip, PLAN_HTML, DATA_RETICLE_LOG, CONTROLS_MARKS_HTML + CONTROLS_FLOWS_HTML, CONTROLS_FOOT_HTML)}`;
|
|
169
190
|
document.body.appendChild(root);
|
|
170
191
|
this.#root = root;
|
|
171
192
|
this.#glow = root.querySelector('[data-reticle-glow]') ?? undefined;
|
|
@@ -185,12 +206,32 @@ export class Presenter {
|
|
|
185
206
|
syncPageBlocker(root, getPresenterSettings(), false);
|
|
186
207
|
this.#glowCtl.setElements(this.#glow, this.#cursor);
|
|
187
208
|
this.#panel.mount(root, this.#glow);
|
|
209
|
+
this.#plan.mount(root);
|
|
188
210
|
if (this.#onHudUse !== undefined) {
|
|
189
211
|
this.#hudTelemetryTeardown = installHudTelemetry(document, root, this.#onHudUse);
|
|
190
212
|
}
|
|
191
213
|
this.setMode(this.#mode);
|
|
214
|
+
this.#restoreLog();
|
|
192
215
|
this.#renderTally();
|
|
193
216
|
}
|
|
217
|
+
#restoreLog() {
|
|
218
|
+
const log = this.#log;
|
|
219
|
+
if (log === undefined || 0 < this.#remembered.length)
|
|
220
|
+
return;
|
|
221
|
+
for (const row of readRememberedLog().slice(-this.#logMax)) {
|
|
222
|
+
const handle = appendLogRow(log, row.kind, row.text, row.ts, this.#logMax, row.actor);
|
|
223
|
+
if (row.result !== undefined)
|
|
224
|
+
handle.result(row.result);
|
|
225
|
+
this.#logBaseMs = this.#now() - row.at;
|
|
226
|
+
this.#runLog.push({
|
|
227
|
+
at: row.at,
|
|
228
|
+
kind: row.kind,
|
|
229
|
+
text: row.text,
|
|
230
|
+
...(row.result === undefined ? {} : { result: row.result }),
|
|
231
|
+
});
|
|
232
|
+
this.#remembered.push(row);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
194
235
|
bindAnnotator(annotator) {
|
|
195
236
|
this.#annotator = annotator;
|
|
196
237
|
const root = this.#root;
|
|
@@ -207,9 +248,10 @@ export class Presenter {
|
|
|
207
248
|
let marks = annotator.markCount;
|
|
208
249
|
chrome.onCount = (n) => {
|
|
209
250
|
if (0 === marks && n > 0)
|
|
210
|
-
this.#shell.
|
|
251
|
+
this.#shell.openView('annotations');
|
|
211
252
|
marks = n;
|
|
212
253
|
};
|
|
254
|
+
chrome.onMarksChange = (items) => this.#shell.paintAnnotations(items);
|
|
213
255
|
if (copy instanceof HTMLElement) {
|
|
214
256
|
copy.addEventListener('click', (e) => {
|
|
215
257
|
e.stopPropagation();
|
|
@@ -253,6 +295,8 @@ export class Presenter {
|
|
|
253
295
|
this.#sessionActive = false;
|
|
254
296
|
this.#logBaseMs = undefined;
|
|
255
297
|
this.#log = undefined;
|
|
298
|
+
this.#remembered = [];
|
|
299
|
+
rememberLog([]);
|
|
256
300
|
this.#root?.remove();
|
|
257
301
|
document.querySelectorAll('style[data-reticle-overlay]').forEach((s) => s.remove());
|
|
258
302
|
this.#root = undefined;
|
|
@@ -414,6 +458,37 @@ export class Presenter {
|
|
|
414
458
|
this.#heartbeatTimer = undefined;
|
|
415
459
|
}
|
|
416
460
|
}
|
|
461
|
+
placeHud(visibility, corner) {
|
|
462
|
+
const root = this.#root;
|
|
463
|
+
if (root === undefined)
|
|
464
|
+
return [];
|
|
465
|
+
const applied = [];
|
|
466
|
+
if (HudVisibility.REMOVED === visibility) {
|
|
467
|
+
this.destroy();
|
|
468
|
+
return [visibility];
|
|
469
|
+
}
|
|
470
|
+
if (HudVisibility.HIDDEN === visibility)
|
|
471
|
+
root.setAttribute(HIDDEN_UNTIL_RESTART_ATTR, '1');
|
|
472
|
+
if (HudVisibility.SHOWN === visibility)
|
|
473
|
+
root.removeAttribute(HIDDEN_UNTIL_RESTART_ATTR);
|
|
474
|
+
if (visibility !== undefined)
|
|
475
|
+
applied.push(visibility);
|
|
476
|
+
const dock = root.querySelector(`[${DOCK_ATTR}]`);
|
|
477
|
+
if (corner !== undefined && dock instanceof HTMLElement) {
|
|
478
|
+
if (HudCorner.BOTTOM_RIGHT === corner)
|
|
479
|
+
resetHudDockPosition(dock);
|
|
480
|
+
else {
|
|
481
|
+
const box = hudLayoutBox(dock);
|
|
482
|
+
const left = corner.endsWith('left') ? 0 : window.innerWidth;
|
|
483
|
+
const top = corner.startsWith('top') ? 0 : window.innerHeight;
|
|
484
|
+
const at = clampHudPosition(left, top, box.width, box.height, window.innerWidth, window.innerHeight);
|
|
485
|
+
applyHudPosition(dock, at.left, at.top);
|
|
486
|
+
}
|
|
487
|
+
applied.push(corner);
|
|
488
|
+
scheduleSyncDockLayout(dock, root);
|
|
489
|
+
}
|
|
490
|
+
return applied;
|
|
491
|
+
}
|
|
417
492
|
setIdleEndMs(ms) {
|
|
418
493
|
if (!Number.isFinite(ms))
|
|
419
494
|
return;
|
|
@@ -446,6 +521,8 @@ export class Presenter {
|
|
|
446
521
|
}
|
|
447
522
|
#clearRunLog() {
|
|
448
523
|
this.#runLog = [];
|
|
524
|
+
this.#remembered = [];
|
|
525
|
+
rememberLog([]);
|
|
449
526
|
this.#tallied = { passes: 0, fails: 0 };
|
|
450
527
|
if (this.#log !== undefined)
|
|
451
528
|
clearLogRows(this.#log);
|
|
@@ -463,12 +540,9 @@ export class Presenter {
|
|
|
463
540
|
else {
|
|
464
541
|
this.#renderTally();
|
|
465
542
|
}
|
|
466
|
-
|
|
467
|
-
const live = SessionState.ACTIVE === this.#panel.state && !this.#shell.isCollapsed();
|
|
468
|
-
syncPageBlocker(this.#root, settings, live);
|
|
469
|
-
}
|
|
543
|
+
this.#syncAnnotator();
|
|
470
544
|
}
|
|
471
|
-
log(kind, text, result) {
|
|
545
|
+
log(kind, text, result, actor) {
|
|
472
546
|
const ms = this.#now();
|
|
473
547
|
this.#glowCtl.markActivity(ms);
|
|
474
548
|
if (this.#log === undefined)
|
|
@@ -484,9 +558,21 @@ export class Presenter {
|
|
|
484
558
|
while (this.#runLog.length > this.#logMax)
|
|
485
559
|
this.#runLog.shift();
|
|
486
560
|
const ts = formatElapsed(ms - this.#logBaseMs);
|
|
487
|
-
const handle = appendLogRow(this.#log, kind, trimmed, ts, this.#logMax);
|
|
561
|
+
const handle = appendLogRow(this.#log, kind, trimmed, ts, this.#logMax, actor);
|
|
488
562
|
if (result !== undefined)
|
|
489
563
|
handle.result(result);
|
|
564
|
+
const kept = {
|
|
565
|
+
kind,
|
|
566
|
+
text: trimmed,
|
|
567
|
+
ts,
|
|
568
|
+
at: ms - this.#logBaseMs,
|
|
569
|
+
...(actor === undefined ? {} : { actor }),
|
|
570
|
+
...(result === undefined ? {} : { result }),
|
|
571
|
+
};
|
|
572
|
+
this.#remembered.push(kept);
|
|
573
|
+
while (this.#remembered.length > this.#logMax)
|
|
574
|
+
this.#remembered.shift();
|
|
575
|
+
rememberLog(this.#remembered);
|
|
490
576
|
if (this.#shell.isCollapsed())
|
|
491
577
|
this.#shell.pulseFab(true);
|
|
492
578
|
this.#renderTally();
|
|
@@ -494,6 +580,8 @@ export class Presenter {
|
|
|
494
580
|
result: (r) => {
|
|
495
581
|
handle.result(r);
|
|
496
582
|
entry.result = r;
|
|
583
|
+
kept.result = r;
|
|
584
|
+
rememberLog(this.#remembered);
|
|
497
585
|
this.#renderTally();
|
|
498
586
|
},
|
|
499
587
|
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { isLastSlide } from './tour-view.js';
|
|
2
|
-
|
|
2
|
+
import { TourAnchor } from '@reticlehq/core/tour';
|
|
3
|
+
import { TOUR_SEEN_KEY_PREFIX } from '../../storage-keys.js';
|
|
4
|
+
export { TOUR_SEEN_KEY_PREFIX };
|
|
5
|
+
export declare const HUD_CONTROL_SELECTORS: Readonly<Partial<Record<TourAnchor, string>>>;
|
|
3
6
|
export declare const tourSeenKey: (projectId: string) => string;
|
|
4
7
|
export interface TourStorage {
|
|
5
8
|
getItem: (key: string) => string | null;
|