@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
|
@@ -5,7 +5,7 @@ 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
7
|
import { DISCOVERY_CALL_URL, FOUNDER_EMAIL, FOUNDER_MAILTO } from '@reticlehq/core';
|
|
8
|
-
import { accountControlHtml } from './presenter-account.js';
|
|
8
|
+
import { ACCOUNT_TEXT, accountControlHtml, } from './presenter-account.js';
|
|
9
9
|
export { SETTINGS_CSS };
|
|
10
10
|
export const OutputDetail = {
|
|
11
11
|
MINIMAL: 'minimal',
|
|
@@ -150,10 +150,19 @@ function settingsCheckRow(key, label, checked) {
|
|
|
150
150
|
}
|
|
151
151
|
export const SETTINGS_ACCOUNT_ATTR = 'data-reticle-settings-account';
|
|
152
152
|
const SETTINGS_ACCOUNT_ROW_ATTR = 'data-reticle-settings-account-row';
|
|
153
|
+
const HELP_TEXT_ATTR = 'data-reticle-settings-helptext';
|
|
153
154
|
const SETTINGS_HARNESS_ROW_ATTR = 'data-reticle-settings-harness-row';
|
|
154
155
|
const HARNESS_HELP = 'Let Reticle drive this app by itself to find defects. Set here or in your dashboard — both write to the same place.';
|
|
155
|
-
const HARNESS_LOCKED_HELP = '
|
|
156
|
-
|
|
156
|
+
const HARNESS_LOCKED_HELP = 'The Harness is not available to this workspace right now. Every workspace gets free Harness credits each month: see Plan in your Reticle dashboard.';
|
|
157
|
+
export function creditsLeft(credits) {
|
|
158
|
+
if (credits === undefined)
|
|
159
|
+
return '';
|
|
160
|
+
const left = Math.max(0, credits.limit - credits.used);
|
|
161
|
+
return 0 === left
|
|
162
|
+
? `All ${String(credits.limit)} Harness credits used this month`
|
|
163
|
+
: `${String(left)} of ${String(credits.limit)} Harness credits left this month`;
|
|
164
|
+
}
|
|
165
|
+
const ACCOUNT_HELP = `Whether this machine is signed in to a Reticle workspace. Press ${ACCOUNT_TEXT.SIGNED_OUT} to sign in through your browser.`;
|
|
157
166
|
export function paintHarnessRow(root, config) {
|
|
158
167
|
const row = root.querySelector(`[${SETTINGS_HARNESS_ROW_ATTR}]`);
|
|
159
168
|
if (!(row instanceof HTMLElement))
|
|
@@ -170,8 +179,11 @@ export function paintHarnessRow(root, config) {
|
|
|
170
179
|
toggle.setAttribute('aria-checked', config.harnessEnabled && usable ? 'true' : 'false');
|
|
171
180
|
toggle.setAttribute('aria-disabled', usable ? 'false' : 'true');
|
|
172
181
|
const help = row.querySelector('[data-reticle-help]');
|
|
182
|
+
const credits = creditsLeft(config.credits);
|
|
173
183
|
if (help instanceof HTMLElement)
|
|
174
|
-
help.title = usable
|
|
184
|
+
help.title = usable
|
|
185
|
+
? [HARNESS_HELP, credits].filter((t) => 0 < t.length).join(' ')
|
|
186
|
+
: HARNESS_LOCKED_HELP;
|
|
175
187
|
}
|
|
176
188
|
export function paintSettingsAccount(root, account, dashboardUrl, details = {}) {
|
|
177
189
|
const row = root.querySelector(`[${SETTINGS_ACCOUNT_ROW_ATTR}]`);
|
|
@@ -188,6 +200,12 @@ const FEEDBACK_TEXT = {
|
|
|
188
200
|
CALL: 'Book a call',
|
|
189
201
|
CALL_TITLE: 'Pick a time to talk it through',
|
|
190
202
|
};
|
|
203
|
+
const KILL_ATTR = 'data-reticle-settings-kill';
|
|
204
|
+
const KILL_TEXT = {
|
|
205
|
+
LABEL: 'Kill Reticle',
|
|
206
|
+
ARMED: 'Click again to kill Reticle',
|
|
207
|
+
WARNING: 'Disconnects Reticle from this page: no HUD, no agent, nothing recorded. To bring it back, restart your dev server or reload the page.',
|
|
208
|
+
};
|
|
191
209
|
export function settingsPanelHtml() {
|
|
192
210
|
const close = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.MIN);
|
|
193
211
|
const caret = hiIconHtml(PresenterIcon.CARET_RIGHT, PRESENTER_ICON_SIZE.HELP);
|
|
@@ -218,9 +236,9 @@ export function settingsPanelHtml() {
|
|
|
218
236
|
<div class="reticle-settings-section">Inspector</div>
|
|
219
237
|
${settingsToggleRow('reactComponents', 'React Components', reactHelp, 'data-reticle-settings-react-row')}
|
|
220
238
|
<div class="reticle-settings-section">Interaction</div>
|
|
221
|
-
${settingsCheckRow('blockPageInteractions', 'Block page
|
|
222
|
-
${settingsCheckRow('clearOnCopy', 'Clear
|
|
223
|
-
${settingsToggleRow('hideUntilRestart', 'Hide
|
|
239
|
+
${settingsCheckRow('blockPageInteractions', 'Block page while adding notes', true)}
|
|
240
|
+
${settingsCheckRow('clearOnCopy', 'Clear notes after copying', false)}
|
|
241
|
+
${settingsToggleRow('hideUntilRestart', 'Hide until reload', hideHelp)}
|
|
224
242
|
${settingsToggleRow('harnessEnabled', 'Autonomous driving', harnessHelp, `${SETTINGS_HARNESS_ROW_ATTR} hidden`)}
|
|
225
243
|
${settingsToggleRow('reduceMotion', 'Reduce motion', motionHelp)}
|
|
226
244
|
<div class="reticle-settings-section">Account</div>
|
|
@@ -231,12 +249,17 @@ export function settingsPanelHtml() {
|
|
|
231
249
|
<div class="reticle-settings-section">Status theme</div>
|
|
232
250
|
${settingsToggleRow('ambientGlow', 'Page glow', glowHelp)}
|
|
233
251
|
<div class="reticle-settings-themes" data-reticle-settings-themes></div>
|
|
234
|
-
|
|
235
|
-
|
|
252
|
+
<div class="reticle-settings-section">Help</div>
|
|
253
|
+
<div class="reticle-settings-foot">
|
|
236
254
|
<button type="button" class="reticle-settings-reset" data-reticle-settings-reset>Reset HUD position</button>
|
|
237
|
-
<button type="button" class="reticle-settings-link" data-reticle-settings-mcp>
|
|
255
|
+
<button type="button" class="reticle-settings-link" data-reticle-settings-mcp>MCP setup guide<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></button>
|
|
238
256
|
<a class="reticle-settings-link" data-reticle-feedback-email href="${FOUNDER_MAILTO}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.EMAIL_TITLE}">${FEEDBACK_TEXT.EMAIL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
|
|
239
257
|
<a class="reticle-settings-link" data-reticle-feedback-call href="${DISCOVERY_CALL_URL}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.CALL_TITLE}">${FEEDBACK_TEXT.CALL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
|
|
258
|
+
<div class="reticle-settings-kill-row">
|
|
259
|
+
<button type="button" class="reticle-settings-kill" ${KILL_ATTR}><span data-reticle-kill-label>${KILL_TEXT.LABEL}</span></button>
|
|
260
|
+
<p class="reticle-settings-kill-sub">${KILL_TEXT.WARNING}</p>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
240
263
|
</div>
|
|
241
264
|
</div>
|
|
242
265
|
</div>`;
|
|
@@ -297,7 +320,7 @@ export class PresenterSettingsPanel {
|
|
|
297
320
|
setHiIcon(this.#btn, PresenterIcon.GEAR, PRESENTER_ICON_SIZE.TOOLBAR);
|
|
298
321
|
this.#btn.addEventListener('click', (e) => {
|
|
299
322
|
e.stopPropagation();
|
|
300
|
-
this.
|
|
323
|
+
this.open();
|
|
301
324
|
});
|
|
302
325
|
}
|
|
303
326
|
root
|
|
@@ -310,8 +333,24 @@ export class PresenterSettingsPanel {
|
|
|
310
333
|
this.#update({ outputDetail: next.value });
|
|
311
334
|
});
|
|
312
335
|
for (const help of root.querySelectorAll('.reticle-settings-help')) {
|
|
336
|
+
help.setAttribute('aria-expanded', 'false');
|
|
313
337
|
help.addEventListener('click', (e) => {
|
|
314
338
|
e.stopPropagation();
|
|
339
|
+
const row = help.closest('.reticle-settings-row');
|
|
340
|
+
if (null === row)
|
|
341
|
+
return;
|
|
342
|
+
const shown = row.querySelector(`[${HELP_TEXT_ATTR}]`);
|
|
343
|
+
if (null !== shown) {
|
|
344
|
+
shown.remove();
|
|
345
|
+
help.setAttribute('aria-expanded', 'false');
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const text = document.createElement('p');
|
|
349
|
+
text.className = 'reticle-settings-helptext';
|
|
350
|
+
text.setAttribute(HELP_TEXT_ATTR, '');
|
|
351
|
+
text.textContent = help.getAttribute('title') ?? '';
|
|
352
|
+
row.appendChild(text);
|
|
353
|
+
help.setAttribute('aria-expanded', 'true');
|
|
315
354
|
});
|
|
316
355
|
}
|
|
317
356
|
for (const toggle of root.querySelectorAll(`[${SETTING_KEY_ATTR}]`)) {
|
|
@@ -399,6 +438,20 @@ export class PresenterSettingsPanel {
|
|
|
399
438
|
if (dock instanceof HTMLElement)
|
|
400
439
|
resetHudDockPosition(dock);
|
|
401
440
|
});
|
|
441
|
+
root.querySelector(`[${KILL_ATTR}]`)?.addEventListener('click', (e) => {
|
|
442
|
+
e.stopPropagation();
|
|
443
|
+
const kill = e.currentTarget;
|
|
444
|
+
if (!(kill instanceof HTMLElement))
|
|
445
|
+
return;
|
|
446
|
+
if ('1' === kill.getAttribute('data-armed')) {
|
|
447
|
+
this.#host.onKill?.();
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
kill.setAttribute('data-armed', '1');
|
|
451
|
+
const label = kill.querySelector('[data-reticle-kill-label]');
|
|
452
|
+
if (label !== null)
|
|
453
|
+
label.textContent = KILL_TEXT.ARMED;
|
|
454
|
+
});
|
|
402
455
|
closeBtn?.addEventListener('click', (e) => {
|
|
403
456
|
e.stopPropagation();
|
|
404
457
|
this.close();
|
|
@@ -434,6 +487,13 @@ export class PresenterSettingsPanel {
|
|
|
434
487
|
close() {
|
|
435
488
|
if (this.#root === undefined)
|
|
436
489
|
return;
|
|
490
|
+
const kill = this.#panel?.querySelector(`[${KILL_ATTR}]`);
|
|
491
|
+
if (kill instanceof HTMLElement) {
|
|
492
|
+
kill.removeAttribute('data-armed');
|
|
493
|
+
const label = kill.querySelector('[data-reticle-kill-label]');
|
|
494
|
+
if (label !== null)
|
|
495
|
+
label.textContent = KILL_TEXT.LABEL;
|
|
496
|
+
}
|
|
437
497
|
this.#root.setAttribute(SETTINGS_ATTR, '0');
|
|
438
498
|
this.#panel?.setAttribute('aria-hidden', 'true');
|
|
439
499
|
this.#btn?.setAttribute('data-active', '0');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LOG_TIME_ATTR } from './chrome/presenter-log.js';
|
|
2
2
|
import { Z_HUD_TOOLTIP } from './presenter-config.js';
|
|
3
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';
|
|
4
|
-
import { HUD_DROP_SHADOW, HUD_SURFACE_FILL } from './chrome/presenter-hud-chrome.js';
|
|
4
|
+
import { HUD_DROP_SHADOW, HUD_GLASS_PAINT, HUD_SURFACE_FILL, } from './chrome/presenter-hud-chrome.js';
|
|
5
5
|
const OVERLAY = 'data-reticle-overlay';
|
|
6
6
|
const HUD = 'data-reticle-hud';
|
|
7
7
|
const CHAT_PANEL = 'data-reticle-chat-panel';
|
|
@@ -23,57 +23,48 @@ export const SHELL_CSS = `
|
|
|
23
23
|
[${OVERLAY}][${STATE}="paused"]{--reticle-state:var(--reticle-c-idle);}
|
|
24
24
|
[${OVERLAY}][${STATE}="ended"]{--reticle-state:var(--reticle-c-ended);}
|
|
25
25
|
[${DOCK_ATTR}]{
|
|
26
|
-
--reticle-surface:
|
|
26
|
+
--reticle-surface:color-mix(in srgb,var(--reticle-hud-surface) 78%,transparent);
|
|
27
27
|
/* No literal here: --reticle-accent is published on the overlay from the chosen status theme.
|
|
28
28
|
Redefining it on the dock made every accented control - toolbar toggles, focus rings, the send
|
|
29
29
|
button - stay blue no matter which theme was picked, because the dock's value won for its own
|
|
30
30
|
subtree. The fallback only matters if the presenter is mounted without settings. */
|
|
31
31
|
--reticle-accent:var(--reticle-c-active,#3b82f6);
|
|
32
32
|
--reticle-accent-soft:color-mix(in srgb,var(--reticle-accent) 18%,transparent);
|
|
33
|
-
--reticle-bg
|
|
34
|
-
--reticle-fg
|
|
35
|
-
--reticle-line:
|
|
33
|
+
--reticle-bg:var(--reticle-hud-ground);--reticle-bg2:var(--reticle-hud-surface);
|
|
34
|
+
--reticle-fg:var(--reticle-hud-text);--reticle-muted:var(--reticle-hud-text-muted);--reticle-faint:var(--reticle-hud-text-faint);
|
|
35
|
+
--reticle-line:var(--reticle-hud-border-strong);--reticle-line2:color-mix(in srgb,var(--reticle-hud-border) 70%,transparent);
|
|
36
36
|
--reticle-read:#d4d4d4;--reticle-ok:#fafafa;--reticle-bad:#f5f5f5;
|
|
37
|
-
--reticle-font:
|
|
38
|
-
--reticle-shell-ease:
|
|
37
|
+
--reticle-font:ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
|
|
38
|
+
--reticle-shell-ease:var(--reticle-hud-ease);
|
|
39
39
|
--reticle-shell-fast:.22s var(--reticle-shell-ease);
|
|
40
40
|
--reticle-mark-accent:var(--reticle-accent);
|
|
41
41
|
position:fixed;right:20px;bottom:20px;left:auto;
|
|
42
42
|
z-index:2147483647;pointer-events:none;display:flex;flex-direction:column;align-items:flex-end;gap:8px;
|
|
43
43
|
overflow:visible;max-width:calc(100vw - 24px);font-family:var(--reticle-font);-webkit-font-smoothing:antialiased;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
*/
|
|
48
|
-
/* ONE width for the chat, the capsule and the toolbar. It used to be 440 with a "compact" 340
|
|
49
|
-
toggle; 340 is the size that actually reads well beside an app, so it is simply the size. */
|
|
50
|
-
--reticle-dock-w:340px;
|
|
44
|
+
/* ONE width for the chat, the capsule and the toolbar: the dock-width token. Two widths made the
|
|
45
|
+
toolbar overhang the panel it belongs to, and the pair read as two unrelated widgets. */
|
|
46
|
+
--reticle-dock-w:var(--reticle-hud-dock-width,320px);
|
|
51
47
|
/* The log is the reason the panel exists, so it gets the height rather than the chrome. */
|
|
52
|
-
--reticle-chat-h:
|
|
48
|
+
--reticle-chat-h:var(--reticle-hud-panel-height,440px);
|
|
53
49
|
opacity:0;transform:translate3d(0,8px,0);transition:opacity var(--reticle-shell-fast),transform var(--reticle-shell-fast);}
|
|
54
50
|
[${DOCK_ATTR}][data-dragged="1"]{left:var(--reticle-hud-x);top:var(--reticle-hud-y);bottom:auto;right:auto;transform:none;}
|
|
55
51
|
[${DOCK_ATTR}][data-dragged="1"][data-on="1"]{transform:none;}
|
|
56
52
|
[${DOCK_ATTR}][data-on="1"]{opacity:1;transform:translate3d(0,0,0);pointer-events:none;}
|
|
57
53
|
[${DOCK_ATTR}][data-on="0"]{opacity:0;pointer-events:none;}
|
|
58
54
|
/**
|
|
59
|
-
* The panel is
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* thing in the whole SDK (+4pp of main thread on the hostile fixture), and the tint buys the look
|
|
63
|
-
* without the bill.
|
|
55
|
+
* The panel is painted by HUD_GLASS_PAINT: an opaque navy fill, lit by the state colour, with that
|
|
56
|
+
* colour glowing behind it. No backdrop-filter: blur(24px) here was measured as the single most
|
|
57
|
+
* expensive thing in the whole SDK.
|
|
64
58
|
*/
|
|
65
59
|
[${CHAT_PANEL}]{
|
|
66
|
-
|
|
67
|
-
radial-gradient(130% 90% at 50% 0%,color-mix(in srgb,var(--reticle-c-active) 18%,transparent),transparent 62%),
|
|
68
|
-
linear-gradient(180deg,rgba(13,15,22,.96),rgba(19,22,32,.94));
|
|
69
|
-
border:1px solid color-mix(in srgb,var(--reticle-c-active) 26%,rgba(255,255,255,.1));
|
|
60
|
+
${HUD_GLASS_PAINT}
|
|
70
61
|
display:none;position:absolute;right:0;left:auto;bottom:calc(100% + 8px);top:auto;z-index:5;
|
|
71
62
|
box-sizing:border-box;width:var(--reticle-dock-w);max-width:min(var(--reticle-dock-w),calc(100vw - 16px));
|
|
63
|
+
height:min(var(--reticle-chat-max-h,var(--reticle-chat-h)),calc(100vh - 120px));
|
|
72
64
|
max-height:min(var(--reticle-chat-max-h,var(--reticle-chat-h)),calc(100vh - 120px));
|
|
73
65
|
flex-direction:column;overflow:hidden;text-align:left;
|
|
74
66
|
color:var(--reticle-fg);font-size:13px;line-height:1.5;
|
|
75
|
-
border-radius:
|
|
76
|
-
box-shadow:${HUD_DROP_SHADOW},0 0 54px -18px var(--reticle-c-active);
|
|
67
|
+
border-radius:var(--reticle-hud-radius-lg);
|
|
77
68
|
contain:layout style paint;
|
|
78
69
|
transform:translateZ(0);
|
|
79
70
|
pointer-events:none;}
|
|
@@ -83,6 +74,9 @@ export const SHELL_CSS = `
|
|
|
83
74
|
right:auto;left:0;}
|
|
84
75
|
[${OVERLAY}][${CHAT_ATTR}="1"] [${CHAT_PANEL}]{
|
|
85
76
|
display:flex;pointer-events:auto;}
|
|
77
|
+
[${CHAT_PANEL}][hidden]{display:none!important;}
|
|
78
|
+
[${DOCK_ATTR}][${CHAT_PLACEMENT_ATTR}="below"] [data-reticle-page-panel]{bottom:auto;top:calc(100% + 8px);}
|
|
79
|
+
[${DOCK_ATTR}][${DOCK_ALIGN_ATTR}="start"] [data-reticle-page-panel]{right:auto;left:0;}
|
|
86
80
|
/**
|
|
87
81
|
* Idle, and not blocking the page: the card is not in use.
|
|
88
82
|
*
|
|
@@ -93,6 +87,10 @@ export const SHELL_CSS = `
|
|
|
93
87
|
[${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}],
|
|
94
88
|
[${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] [data-reticle-log]{
|
|
95
89
|
pointer-events:none;}
|
|
90
|
+
/* ...except a log with more than it shows: a feed nobody can scroll back through is not a log. */
|
|
91
|
+
[${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] [data-reticle-log][data-reticle-log-scrollable],
|
|
92
|
+
[${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] .reticle-flow-strip{
|
|
93
|
+
pointer-events:auto;}
|
|
96
94
|
[${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] :is(button,a,input,select,textarea){
|
|
97
95
|
pointer-events:auto;}
|
|
98
96
|
/**
|
|
@@ -136,6 +134,8 @@ export const SHELL_CSS = `
|
|
|
136
134
|
[${CHAT_PANEL}] .reticle-head-account:empty{display:none;}
|
|
137
135
|
[${CHAT_PANEL}] .reticle-chat-brand .reticle-mark{height:14px;width:auto;}
|
|
138
136
|
[${CHAT_PANEL}] .reticle-chat-brandname{font-size:12.5px;font-weight:600;letter-spacing:.01em;}
|
|
137
|
+
[${CHAT_PANEL}] .reticle-view-heading{display:flex;justify-content:space-between;align-items:baseline;gap:8px;min-height:28px;box-sizing:border-box;padding:6px 12px 4px;border-bottom:1px solid var(--reticle-hud-border);}
|
|
138
|
+
[${CHAT_PANEL}] .reticle-view-heading strong{font-size:11px;font-weight:600;}
|
|
139
139
|
/* No state word here: the activity strip immediately below already says "idle · 21s", and the
|
|
140
140
|
dot in front of it carries the same colour. One fact, one place. */
|
|
141
141
|
[${CHAT_PILL_ATTR}] .reticle-chat-pill-text{
|
|
@@ -255,13 +255,13 @@ export const SHELL_CSS = `
|
|
|
255
255
|
[${HUD}] .reticle-toolbar-actions{
|
|
256
256
|
display:inline-flex;align-items:center;gap:2px;flex:none;
|
|
257
257
|
padding:2px;border-radius:999px;background:rgba(0,0,0,.2);}
|
|
258
|
-
[${HUD}] .reticle-toolbar-chrome{display:
|
|
258
|
+
[${HUD}] .reticle-toolbar-chrome{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));align-items:center;gap:var(--reticle-hud-space-1);flex:1;min-width:0;}
|
|
259
259
|
[${HUD}] .reticle-tb-sep{width:1px;height:14px;background:rgba(255,255,255,.12);margin:0 4px;flex:none;align-self:center;}
|
|
260
260
|
|
|
261
261
|
[${HUD}] .reticle-tb-wrap{position:relative;display:flex;align-items:center;justify-content:center;overflow:visible;}
|
|
262
262
|
[${HUD}] .reticle-tb-btn{
|
|
263
263
|
flex:none;display:inline-flex;align-items:center;justify-content:center;
|
|
264
|
-
width:
|
|
264
|
+
width:var(--reticle-hud-control-size);height:var(--reticle-hud-control-size);padding:0;border:none;border-radius:var(--reticle-hud-radius-pill);cursor:pointer;
|
|
265
265
|
background:transparent;color:rgba(255,255,255,.85);line-height:0;
|
|
266
266
|
transition:background-color .15s ease,color .15s ease,transform .1s ease,opacity .2s ease;}
|
|
267
267
|
[${HUD}] .reticle-tb-btn:hover{background:rgba(255,255,255,.12);color:#fff;}
|
|
@@ -294,18 +294,6 @@ export const SHELL_CSS = `
|
|
|
294
294
|
color:#fff;background:rgba(255,255,255,.14);}
|
|
295
295
|
[${HUD}] .reticle-tb-btn[data-danger]:hover:not(:disabled){color:#ff383c;
|
|
296
296
|
background:color-mix(in srgb, #ff383c 25%, transparent);}
|
|
297
|
-
/**
|
|
298
|
-
* The toolbar is a FIXED number of slots.
|
|
299
|
-
*
|
|
300
|
-
* Copy and Export appear when a session ends, and the bar is already full - eleven icons in a pill
|
|
301
|
-
* sized for nine renders the last one outside the rounded box. They take the two slots Pause and End
|
|
302
|
-
* vacate: neither can do anything to an ended session, so the bar swaps two dead controls for two
|
|
303
|
-
* live ones and never changes width.
|
|
304
|
-
*/
|
|
305
|
-
[${HUD}] .reticle-tb-btn--export{display:none;}
|
|
306
|
-
[${OVERLAY}][${STATE}="ended"] [${HUD}] .reticle-tb-btn--export{display:inline-flex;}
|
|
307
|
-
[${OVERLAY}][${STATE}="ended"] [${HUD}] [data-reticle-pause],
|
|
308
|
-
[${OVERLAY}][${STATE}="ended"] [${HUD}] [data-reticle-end]{display:none;}
|
|
309
297
|
[${HUD}] .reticle-tb-tip{
|
|
310
298
|
position:absolute;bottom:calc(100% + 14px);left:50%;transform:translateX(-50%) scale(.95);
|
|
311
299
|
padding:6px 10px;background:#1a1a1a;color:rgba(255,255,255,.9);font-size:12px;font-weight:500;
|
|
@@ -359,7 +347,7 @@ export const SHELL_CSS = `
|
|
|
359
347
|
[${HUD}] .reticle-hi-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1;flex-shrink:0;color:inherit;}
|
|
360
348
|
[${HUD}] .reticle-hi-icon svg{display:block;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
|
|
361
349
|
[${HUD}] .reticle-live{display:none;}
|
|
362
|
-
[${CHAT_PANEL}] .reticle-act-strip{flex:none;display:flex;align-items:center;gap:
|
|
350
|
+
[${CHAT_PANEL}] .reticle-act-strip{flex:none;display:flex;align-items:center;gap:7px;min-height:36px;box-sizing:border-box;padding:4px 12px;
|
|
363
351
|
border-bottom:1px solid rgba(255,255,255,.07);background:rgba(0,0,0,.22);}
|
|
364
352
|
[${CHAT_PANEL}] .reticle-act-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--reticle-faint);
|
|
365
353
|
box-shadow:0 0 0 2px rgba(255,255,255,.04);transition:background .2s,box-shadow .2s;}
|
|
@@ -387,6 +375,15 @@ export const SHELL_CSS = `
|
|
|
387
375
|
@keyframes reticle-idle-pulse{0%,100%{opacity:.45;transform:scale(.92)}50%{opacity:1;transform:scale(1)}}
|
|
388
376
|
[${CHAT_PANEL}] .reticle-act{display:block;flex:1;min-width:0;color:var(--reticle-muted);font-size:11px;
|
|
389
377
|
font-variant-numeric:tabular-nums;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
378
|
+
[${CHAT_PANEL}] .reticle-act-actions{display:flex;align-items:center;gap:4px;flex:none;margin-left:auto;}
|
|
379
|
+
[${CHAT_PANEL}] .reticle-status-btn{position:relative;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;
|
|
380
|
+
border:1px solid var(--reticle-line);border-radius:var(--reticle-hud-radius-sm);background:transparent;color:var(--reticle-muted);cursor:pointer;}
|
|
381
|
+
[${CHAT_PANEL}] .reticle-status-btn[hidden]{display:none;}
|
|
382
|
+
[${CHAT_PANEL}] .reticle-status-btn:hover:not(:disabled){background:var(--reticle-hud-hover);color:var(--reticle-fg);}
|
|
383
|
+
[${CHAT_PANEL}] .reticle-status-btn:focus-visible{outline:2px solid var(--reticle-accent);outline-offset:2px;}
|
|
384
|
+
[${CHAT_PANEL}] .reticle-status-btn:disabled{opacity:.35;cursor:not-allowed;}
|
|
385
|
+
[${CHAT_PANEL}] .reticle-status-stop:hover:not(:disabled){color:var(--reticle-state);border-color:var(--reticle-state);}
|
|
386
|
+
[${CHAT_PANEL}] .reticle-act-actions .reticle-pause-badge{display:none;position:static;transform:none;padding:2px 5px;font-size:8px;}
|
|
390
387
|
[${CHAT_PANEL}] .reticle-act-strip[data-liveness="active"] .reticle-act{color:var(--reticle-fg);}
|
|
391
388
|
[${HUD}] .reticle-pass{color:var(--reticle-ok);}[${HUD}] .reticle-fail{color:var(--reticle-bad);}
|
|
392
389
|
/**
|
|
@@ -408,6 +405,6 @@ export const SHELL_CSS = `
|
|
|
408
405
|
--reticle-accent:var(--reticle-state);
|
|
409
406
|
--reticle-accent-soft:color-mix(in srgb,var(--reticle-state) 18%,transparent);}
|
|
410
407
|
@media (max-width:480px){
|
|
411
|
-
[${CHAT_PANEL}]{width:min(100vw - 24px,320px);max-height:min(
|
|
408
|
+
[${CHAT_PANEL}]{width:min(100vw - 24px,320px);max-height:min(440px,calc(100vh - 100px));}
|
|
412
409
|
[${OVERLAY}][${MIN_ATTR}="0"] [${HUD}]{max-width:calc(100vw - 24px);}
|
|
413
410
|
}`;
|
|
@@ -3,6 +3,8 @@ import { PresenterReport } from './presenter-report.js';
|
|
|
3
3
|
import type { AccountState } from '@reticlehq/core';
|
|
4
4
|
import { type AccountDetails } from './presenter-account.js';
|
|
5
5
|
import { type OfferState } from './carousel/offer-card.js';
|
|
6
|
+
import { type ChatView } from './presenter-chat-views.js';
|
|
7
|
+
import type { AnnotationItem } from '../review/annotator.js';
|
|
6
8
|
import { type SettingsHost } from './presenter-settings.js';
|
|
7
9
|
interface HudShellCallbacks {
|
|
8
10
|
onChatOpen?: () => void;
|
|
@@ -11,13 +13,18 @@ interface HudShellCallbacks {
|
|
|
11
13
|
onAnnotateToggle?: (on: boolean) => void;
|
|
12
14
|
onCollapse?: () => void;
|
|
13
15
|
onSyncNow?: () => void;
|
|
16
|
+
onHarness?: (enabled: boolean) => void;
|
|
17
|
+
onSignIn?: () => void;
|
|
14
18
|
settings?: SettingsHost;
|
|
15
19
|
}
|
|
16
20
|
export declare class HudShell {
|
|
17
21
|
#private;
|
|
18
22
|
paintHarness(config: HarnessConfig | undefined): void;
|
|
23
|
+
paintImpact(verdicts: number): void;
|
|
24
|
+
paintAnnotations(items: readonly AnnotationItem[]): void;
|
|
25
|
+
openView(view: ChatView): void;
|
|
19
26
|
paintAccount(account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
|
|
20
|
-
paintOffer(offer: OfferState | undefined): void;
|
|
27
|
+
paintOffer(offer: OfferState | undefined, notices?: readonly unknown[]): void;
|
|
21
28
|
constructor(callbacks?: HudShellCallbacks);
|
|
22
29
|
static dockHtml(actStripHtml: string, bannerHtml: string, logAttr: string, flowsHtml: string, footHtml: string): string;
|
|
23
30
|
get report(): PresenterReport;
|