@reticlehq/browser 3.5.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 -0
- package/dist/actions/actions.js +25 -16
- package/dist/actions/danger-context.js +1 -1
- package/dist/connect-options.d.ts +1 -0
- package/dist/dom/a11y.js +13 -4
- 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/query.d.ts +1 -0
- package/dist/dom/query.js +38 -11
- 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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LogActor, LogKind, LogResult } from './presenter-log.js';
|
|
2
|
+
export interface RememberedRow {
|
|
3
|
+
kind: LogKind;
|
|
4
|
+
text: string;
|
|
5
|
+
ts: string;
|
|
6
|
+
at: number;
|
|
7
|
+
actor?: LogActor;
|
|
8
|
+
result?: LogResult;
|
|
9
|
+
}
|
|
10
|
+
export declare function readRememberedLog(): RememberedRow[];
|
|
11
|
+
export declare function rememberLog(rows: readonly RememberedRow[]): void;
|
|
12
|
+
export declare function claimLog(owner: string | undefined): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ReticleStorageKey } from '../../storage-keys.js';
|
|
2
|
+
const LOG_STORAGE_KEY = ReticleStorageKey.PRESENTER_LOG;
|
|
3
|
+
export function readRememberedLog() {
|
|
4
|
+
try {
|
|
5
|
+
const raw = JSON.parse(globalThis.sessionStorage.getItem(LOG_STORAGE_KEY) ?? '[]');
|
|
6
|
+
return Array.isArray(raw)
|
|
7
|
+
? raw.filter((row) => 'object' === typeof row &&
|
|
8
|
+
null !== row &&
|
|
9
|
+
'string' === typeof row.text &&
|
|
10
|
+
'string' === typeof row.kind &&
|
|
11
|
+
'string' === typeof row.ts &&
|
|
12
|
+
'number' === typeof row.at)
|
|
13
|
+
: [];
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function rememberLog(rows) {
|
|
20
|
+
try {
|
|
21
|
+
globalThis.sessionStorage.setItem(LOG_STORAGE_KEY, JSON.stringify(rows));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function claimLog(owner) {
|
|
27
|
+
try {
|
|
28
|
+
const now = owner ?? '';
|
|
29
|
+
const before = globalThis.sessionStorage.getItem(ReticleStorageKey.PRESENTER_LOG_OWNER);
|
|
30
|
+
globalThis.sessionStorage.setItem(ReticleStorageKey.PRESENTER_LOG_OWNER, now);
|
|
31
|
+
if (null === before || before === now)
|
|
32
|
+
return false;
|
|
33
|
+
globalThis.sessionStorage.removeItem(LOG_STORAGE_KEY);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -2,6 +2,7 @@ export declare const HUD_SURFACE_CLASS = "reticle-hud-surface";
|
|
|
2
2
|
export declare const HUD_SURFACE_FILL: string;
|
|
3
3
|
export declare const HUD_SURFACE_PAINT: string;
|
|
4
4
|
export declare const HUD_DROP_SHADOW: string;
|
|
5
|
+
export declare const HUD_GLASS_PAINT: string;
|
|
5
6
|
export declare const HUD_CHROME_CSS: string;
|
|
6
7
|
export declare const HUD_LOG_WELL_CLASS = "reticle-hud-log-well";
|
|
7
8
|
export declare const HUD_LOG_WELL_CSS: string;
|
|
@@ -2,6 +2,12 @@ export const HUD_SURFACE_CLASS = 'reticle-hud-surface';
|
|
|
2
2
|
export const HUD_SURFACE_FILL = `linear-gradient(165deg,#121218 0%,#09090c 42%,#000 100%)`;
|
|
3
3
|
export const HUD_SURFACE_PAINT = `background:${HUD_SURFACE_FILL};box-shadow:inset 0 1px 0 rgba(255,255,255,.09),0 0 0 1px rgba(255,255,255,.09);`;
|
|
4
4
|
export const HUD_DROP_SHADOW = '0 16px 40px rgba(0,0,0,.58),0 0 0 1px rgba(255,255,255,.08)';
|
|
5
|
+
export const HUD_GLASS_PAINT = [
|
|
6
|
+
'background:radial-gradient(130% 80% at 50% 0%,color-mix(in srgb,var(--reticle-c-active) 20%,transparent),transparent 62%),',
|
|
7
|
+
'linear-gradient(180deg,#121a2e,#080b14);',
|
|
8
|
+
'border:1px solid color-mix(in srgb,var(--reticle-c-active) 30%,rgba(255,255,255,.1));',
|
|
9
|
+
`box-shadow:${HUD_DROP_SHADOW},0 0 64px -12px color-mix(in srgb,var(--reticle-c-active) 75%,transparent);`,
|
|
10
|
+
].join('');
|
|
5
11
|
export const HUD_CHROME_CSS = `
|
|
6
12
|
.${HUD_SURFACE_CLASS}{
|
|
7
13
|
position:relative;overflow:hidden;
|
|
@@ -25,7 +31,7 @@ export const HUD_LOG_WELL_CSS = `
|
|
|
25
31
|
as tall as its rows, which left the empty-state line floating near the top of an otherwise
|
|
26
32
|
empty panel instead of centred in it. */
|
|
27
33
|
position:relative;display:flex;flex-direction:column;
|
|
28
|
-
flex:1 1 auto;height:
|
|
34
|
+
flex:1 1 auto;height:240px;min-height:120px;max-height:300px;overflow:hidden;
|
|
29
35
|
contain:layout style paint;
|
|
30
36
|
margin:0 6px;border-radius:12px;background:transparent;}
|
|
31
37
|
.${HUD_LOG_WELL_CLASS} > *{position:relative;z-index:1;}`;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { PresenterMode } from '@reticlehq/core';
|
|
2
|
-
import { LOG_KIND, LOG_RESULT, type LogKind, type LogResult } from './log-kinds.js';
|
|
3
|
-
export { LOG_KIND, LOG_RESULT };
|
|
4
|
-
export type { LogKind, LogResult };
|
|
2
|
+
import { LOG_ACTOR, LOG_KIND, LOG_RESULT, type LogActor, type LogKind, type LogResult } from './log-kinds.js';
|
|
3
|
+
export { LOG_ACTOR, LOG_KIND, LOG_RESULT };
|
|
4
|
+
export type { LogActor, LogKind, LogResult };
|
|
5
5
|
export declare const CHIP_LABEL: Record<PresenterMode, string>;
|
|
6
6
|
export declare const DATA_RETICLE_LOG = "data-reticle-log";
|
|
7
7
|
export declare const LOG_TIME_ATTR = "data-reticle-log-time";
|
|
8
8
|
export declare const LOG_CSS: string;
|
|
9
|
+
export declare const LOG_SCROLLABLE_ATTR = "data-reticle-log-scrollable";
|
|
9
10
|
export declare function settleLogAtLatest(container: HTMLElement): void;
|
|
10
11
|
export interface LogHandle {
|
|
11
12
|
result(r: LogResult): void;
|
|
@@ -15,4 +16,4 @@ export declare function clearLogRows(container: HTMLElement): void;
|
|
|
15
16
|
export declare function clampLogMax(n: number | undefined): number;
|
|
16
17
|
export declare function humanDuration(ms: number): string;
|
|
17
18
|
export declare function formatElapsed(ms: number): string;
|
|
18
|
-
export declare function appendLogRow(container: HTMLElement, kind: LogKind, text: string, ts: string, logMax: number): LogHandle;
|
|
19
|
+
export declare function appendLogRow(container: HTMLElement, kind: LogKind, text: string, ts: string, logMax: number, actor?: LogActor): LogHandle;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PresenterMode } from '@reticlehq/core';
|
|
2
|
-
import { LOG_KIND, LOG_RESULT } from './log-kinds.js';
|
|
2
|
+
import { LOG_ACTOR, LOG_KIND, LOG_RESULT, } from './log-kinds.js';
|
|
3
3
|
import { nativeSetTimeout } from '../../timers/native/native-timers.js';
|
|
4
4
|
import { PresenterIcon, PRESENTER_ICON_SIZE, hiIcon, } from '../icons/presenter-icons.js';
|
|
5
5
|
const DEFAULT_LOG_MAX = 50;
|
|
6
|
-
export { LOG_KIND, LOG_RESULT };
|
|
6
|
+
export { LOG_ACTOR, LOG_KIND, LOG_RESULT };
|
|
7
7
|
const LOG_CHIP = { read: 'READ', act: 'ACT', narration: '', human: '' };
|
|
8
8
|
const LOG_CHIP_ICON = {
|
|
9
9
|
read: PresenterIcon.VIEW,
|
|
@@ -20,7 +20,15 @@ const LOG_CHIP_MODE = {
|
|
|
20
20
|
narration: PresenterMode.IDLE,
|
|
21
21
|
human: PresenterMode.IDLE,
|
|
22
22
|
};
|
|
23
|
-
const RESULT_GLYPH = { pass: '', fail: 'Fail' };
|
|
23
|
+
const RESULT_GLYPH = { pass: '✓', fail: 'Fail' };
|
|
24
|
+
const HANDOVER_TEXT = {
|
|
25
|
+
agent: 'Your agent is driving',
|
|
26
|
+
harness: 'Reticle Harness is driving',
|
|
27
|
+
};
|
|
28
|
+
const LAST_ACTOR_ATTR = 'data-reticle-log-actor';
|
|
29
|
+
const DATA_ACTOR = 'data-actor';
|
|
30
|
+
const DATA_STATE = 'data-state';
|
|
31
|
+
const HANDOVER_KIND = 'handover';
|
|
24
32
|
const RESULT_CLASS = { pass: 'reticle-pass', fail: 'reticle-fail' };
|
|
25
33
|
export const DATA_RETICLE_LOG = 'data-reticle-log';
|
|
26
34
|
const DATA_RETICLE_LOG_ROW = 'data-reticle-log-row';
|
|
@@ -69,10 +77,34 @@ export const LOG_CSS = `
|
|
|
69
77
|
padding:8px 12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);
|
|
70
78
|
border-radius:16px 16px 4px 16px;box-shadow:inset 0 1px 0 rgba(255,255,255,.08);}
|
|
71
79
|
[data-reticle-log-row][data-kind="human"] .reticle-log-text{color:var(--reticle-fg);font-size:12px;line-height:1.45;}
|
|
80
|
+
/* Rows arrive, rather than appear: the person watching should see the log move. */
|
|
81
|
+
[data-reticle-log-row]{animation:reticle-row-in .22s var(--reticle-hud-ease,ease) both;}
|
|
82
|
+
@keyframes reticle-row-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
|
|
83
|
+
@media (prefers-reduced-motion:reduce){[data-reticle-log-row]{animation:none;}}
|
|
84
|
+
/* The step in flight pulses until its verdict lands; then it says how it ended. */
|
|
85
|
+
[data-reticle-log-row][data-state="running"] .reticle-res{display:inline-block;width:6px;height:6px;margin-top:5px;
|
|
86
|
+
border-radius:50%;background:var(--reticle-c-active);opacity:1;animation:reticle-row-pulse 1s ease-in-out infinite;}
|
|
87
|
+
@keyframes reticle-row-pulse{0%,100%{opacity:.35;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}
|
|
88
|
+
[data-reticle-log] .reticle-res.reticle-pass{display:inline;color:#4ade80;font-size:10px;opacity:.9;}
|
|
89
|
+
[data-reticle-log] .reticle-res.reticle-fail{color:#fca5a5;background:rgba(239,68,68,.16);border-radius:999px;padding:1px 6px;font-size:8px;opacity:1;}
|
|
90
|
+
/* The Harness's rows wear its own colour, so two drivers never read as one. */
|
|
91
|
+
[data-reticle-log-row][data-actor="harness"]{--reticle-row-accent:#a78bfa;}
|
|
92
|
+
[data-reticle-log-row][data-actor="harness"] .reticle-chip{color:#a78bfa;}
|
|
93
|
+
[data-reticle-log-row][data-actor="harness"]:not([data-kind="handover"]){box-shadow:inset 2px 0 0 color-mix(in srgb,#a78bfa 55%,transparent);padding-left:8px;}
|
|
94
|
+
[data-reticle-log-row][data-kind="handover"]{align-items:center;gap:8px;margin:8px 0 4px;padding:0;
|
|
95
|
+
font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--reticle-row-accent,var(--reticle-c-active));}
|
|
96
|
+
[data-reticle-log-row][data-kind="handover"]::before,[data-reticle-log-row][data-kind="handover"]::after{
|
|
97
|
+
content:"";flex:1;height:1px;background:color-mix(in srgb,var(--reticle-row-accent,var(--reticle-c-active)) 40%,transparent);}
|
|
98
|
+
[data-reticle-log-row][data-kind="handover"] .reticle-log-text{flex:none;color:inherit;}
|
|
99
|
+
/* What the Harness or the daemon says about a drive reads as a notice, not an aside. */
|
|
100
|
+
[data-reticle-log-row][data-kind="narration"]{font-style:normal;color:var(--reticle-fg);margin:4px 0;padding:7px 10px;
|
|
101
|
+
border-radius:10px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);}
|
|
72
102
|
`;
|
|
73
103
|
function scrollLogToLatest(container) {
|
|
74
104
|
container.scrollTop = container.scrollHeight;
|
|
105
|
+
container.toggleAttribute(LOG_SCROLLABLE_ATTR, container.scrollHeight > container.clientHeight + 1);
|
|
75
106
|
}
|
|
107
|
+
export const LOG_SCROLLABLE_ATTR = 'data-reticle-log-scrollable';
|
|
76
108
|
export function settleLogAtLatest(container) {
|
|
77
109
|
scrollLogToLatest(container);
|
|
78
110
|
requestAnimationFrame(() => {
|
|
@@ -111,10 +143,27 @@ export function humanDuration(ms) {
|
|
|
111
143
|
export function formatElapsed(ms) {
|
|
112
144
|
return humanDuration(ms);
|
|
113
145
|
}
|
|
114
|
-
export function appendLogRow(container, kind, text, ts, logMax) {
|
|
146
|
+
export function appendLogRow(container, kind, text, ts, logMax, actor = LOG_ACTOR.AGENT) {
|
|
147
|
+
const driven = kind === LOG_KIND.ACT || kind === LOG_KIND.READ;
|
|
148
|
+
if (driven && (container.getAttribute(LAST_ACTOR_ATTR) ?? LOG_ACTOR.AGENT) !== actor) {
|
|
149
|
+
const divider = document.createElement('div');
|
|
150
|
+
divider.setAttribute(DATA_RETICLE_LOG_ROW, '');
|
|
151
|
+
divider.setAttribute(DATA_KIND, HANDOVER_KIND);
|
|
152
|
+
divider.setAttribute(DATA_ACTOR, actor);
|
|
153
|
+
const label = document.createElement('span');
|
|
154
|
+
label.className = LOG_TEXT_CLASS;
|
|
155
|
+
label.textContent = HANDOVER_TEXT[actor];
|
|
156
|
+
divider.appendChild(label);
|
|
157
|
+
container.appendChild(divider);
|
|
158
|
+
}
|
|
159
|
+
if (driven)
|
|
160
|
+
container.setAttribute(LAST_ACTOR_ATTR, actor);
|
|
115
161
|
const row = document.createElement('div');
|
|
116
162
|
row.setAttribute(DATA_RETICLE_LOG_ROW, '');
|
|
117
163
|
row.setAttribute(DATA_KIND, kind);
|
|
164
|
+
row.setAttribute(DATA_ACTOR, actor);
|
|
165
|
+
if (kind === LOG_KIND.ACT)
|
|
166
|
+
row.setAttribute(DATA_STATE, 'running');
|
|
118
167
|
const tsEl = document.createElement('span');
|
|
119
168
|
tsEl.setAttribute(LOG_TIME_ATTR, '');
|
|
120
169
|
tsEl.textContent = ts;
|
|
@@ -153,8 +202,9 @@ export function appendLogRow(container, kind, text, ts, logMax) {
|
|
|
153
202
|
});
|
|
154
203
|
return {
|
|
155
204
|
result: (r) => {
|
|
205
|
+
row.setAttribute(DATA_STATE, r);
|
|
156
206
|
if (r === LOG_RESULT.PASS) {
|
|
157
|
-
resEl.textContent =
|
|
207
|
+
resEl.textContent = RESULT_GLYPH.pass;
|
|
158
208
|
resEl.className = `${LOG_RES_CLASS} ${RESULT_CLASS.pass}`;
|
|
159
209
|
return;
|
|
160
210
|
}
|
|
@@ -7,8 +7,12 @@ export declare const REPORT_LINKS: {
|
|
|
7
7
|
};
|
|
8
8
|
export declare const REPORT_TEXT: {
|
|
9
9
|
readonly TITLE: "Impact";
|
|
10
|
+
readonly COVERAGE: "Reticle Coverage";
|
|
11
|
+
readonly COVERAGE_HELP: "How much of this app Reticle has reached, touched and proved, from the coverage ledger in .reticle";
|
|
10
12
|
readonly PROJECT: "This project";
|
|
11
|
-
readonly GLOBAL: "
|
|
13
|
+
readonly GLOBAL: "All projects";
|
|
14
|
+
readonly GLOBAL_TITLE: "Every project on this computer";
|
|
15
|
+
readonly SCOPE_LABEL: "Show impact for";
|
|
12
16
|
readonly HERO_DEFECTS: "checks Reticle refused to pass";
|
|
13
17
|
readonly VERDICTS: "Verdicts";
|
|
14
18
|
readonly PASSED: "passed";
|
|
@@ -27,6 +31,8 @@ export declare const REPORT_TEXT: {
|
|
|
27
31
|
readonly CHART: "Verdicts, last 30 days";
|
|
28
32
|
readonly DEFECTS: "What broke";
|
|
29
33
|
readonly DEFECTS_MORE: "Manage all of them on the dashboard — triage, assign, and push to GitHub";
|
|
34
|
+
readonly DEFECTS_SEE_ALL: "See all on the dashboard";
|
|
35
|
+
readonly DEFECTS_SEE_ALL_TITLE: "Sign up free, link this project, and see every bug Reticle caught";
|
|
30
36
|
readonly DEFECT_LINK_TITLE: "Open on the dashboard to triage or push to GitHub";
|
|
31
37
|
readonly LOCAL_ONLY: "This record stops at this machine.";
|
|
32
38
|
readonly LOCAL_ONLY_ACTION: "reticle login";
|
|
@@ -48,3 +54,7 @@ export declare function buildXShareUrl(text: string): string;
|
|
|
48
54
|
export declare function buildLinkedInShareUrl(): string;
|
|
49
55
|
export declare function buildReferralText(): string;
|
|
50
56
|
export declare function parseImpactSnapshot(value: unknown): ImpactSnapshot | undefined;
|
|
57
|
+
export declare const COVERAGE_LEVELS: readonly {
|
|
58
|
+
key: string;
|
|
59
|
+
label: string;
|
|
60
|
+
}[];
|
|
@@ -8,8 +8,12 @@ export const REPORT_LINKS = {
|
|
|
8
8
|
const SHARE_VIA_HANDLE = '';
|
|
9
9
|
export const REPORT_TEXT = {
|
|
10
10
|
TITLE: 'Impact',
|
|
11
|
+
COVERAGE: 'Reticle Coverage',
|
|
12
|
+
COVERAGE_HELP: 'How much of this app Reticle has reached, touched and proved, from the coverage ledger in .reticle',
|
|
11
13
|
PROJECT: 'This project',
|
|
12
|
-
GLOBAL: '
|
|
14
|
+
GLOBAL: 'All projects',
|
|
15
|
+
GLOBAL_TITLE: 'Every project on this computer',
|
|
16
|
+
SCOPE_LABEL: 'Show impact for',
|
|
13
17
|
HERO_DEFECTS: 'checks Reticle refused to pass',
|
|
14
18
|
VERDICTS: 'Verdicts',
|
|
15
19
|
PASSED: 'passed',
|
|
@@ -28,6 +32,8 @@ export const REPORT_TEXT = {
|
|
|
28
32
|
CHART: 'Verdicts, last 30 days',
|
|
29
33
|
DEFECTS: 'What broke',
|
|
30
34
|
DEFECTS_MORE: 'Manage all of them on the dashboard — triage, assign, and push to GitHub',
|
|
35
|
+
DEFECTS_SEE_ALL: 'See all on the dashboard',
|
|
36
|
+
DEFECTS_SEE_ALL_TITLE: 'Sign up free, link this project, and see every bug Reticle caught',
|
|
31
37
|
DEFECT_LINK_TITLE: 'Open on the dashboard to triage or push to GitHub',
|
|
32
38
|
LOCAL_ONLY: 'This record stops at this machine.',
|
|
33
39
|
LOCAL_ONLY_ACTION: 'reticle login',
|
|
@@ -93,3 +99,10 @@ export function parseImpactSnapshot(value) {
|
|
|
93
99
|
const parsed = ImpactSnapshotSchema.safeParse(value);
|
|
94
100
|
return parsed.success ? parsed.data : undefined;
|
|
95
101
|
}
|
|
102
|
+
export const COVERAGE_LEVELS = [
|
|
103
|
+
{ key: 'reached', label: 'routes reached' },
|
|
104
|
+
{ key: 'touched', label: 'controls touched' },
|
|
105
|
+
{ key: 'proved', label: 'controls proved' },
|
|
106
|
+
{ key: 'branched', label: 'write failures driven' },
|
|
107
|
+
{ key: 'executed', label: 'code executed' },
|
|
108
|
+
];
|
|
@@ -3,7 +3,9 @@ import { HudPanel, HudToggle, HudView } from '@reticlehq/core';
|
|
|
3
3
|
import { isReticleUi } from '../dom/dom-ignore.js';
|
|
4
4
|
import { nativeSetTimeout } from '../timers/native/native-timers.js';
|
|
5
5
|
import { CHAT_ATTR, MIN_ATTR, REPORT_ATTR, SETTINGS_ATTR } from './presenter-config.js';
|
|
6
|
+
import { CAROUSEL_SLIDE_ATTR } from './carousel/carousel.js';
|
|
6
7
|
const PREFIX = 'data-reticle-';
|
|
8
|
+
const PAGE_OPEN_ATTR = 'data-reticle-page-open';
|
|
7
9
|
const TOGGLE_ROLES = new Set(['switch', 'checkbox']);
|
|
8
10
|
export function controlIdOf(el) {
|
|
9
11
|
for (const attr of Array.from(el.attributes)) {
|
|
@@ -36,6 +38,11 @@ function viewOf(root) {
|
|
|
36
38
|
if ('1' === root.getAttribute(REPORT_ATTR)) {
|
|
37
39
|
return { view: HudView.EXPANDED, panel: HudPanel.REPORT };
|
|
38
40
|
}
|
|
41
|
+
const page = root.getAttribute(PAGE_OPEN_ATTR);
|
|
42
|
+
if ('flows' === page)
|
|
43
|
+
return { view: HudView.EXPANDED, panel: HudPanel.FLOWS };
|
|
44
|
+
if ('annotations' === page)
|
|
45
|
+
return { view: HudView.EXPANDED, panel: HudPanel.NOTES };
|
|
39
46
|
if ('1' === root.getAttribute(CHAT_ATTR))
|
|
40
47
|
return { view: HudView.EXPANDED, panel: HudPanel.CHAT };
|
|
41
48
|
return { view: HudView.COLLAPSED, panel: HudPanel.NONE };
|
|
@@ -73,15 +80,37 @@ export function installHudTelemetry(doc, root, report) {
|
|
|
73
80
|
last = key;
|
|
74
81
|
send(now);
|
|
75
82
|
};
|
|
83
|
+
let lastSlide = '';
|
|
84
|
+
const onSlide = () => {
|
|
85
|
+
if (HudPanel.CHAT !== viewOf(root).panel)
|
|
86
|
+
return;
|
|
87
|
+
const shown = root.querySelector(`[${CAROUSEL_SLIDE_ATTR}]:not([hidden])`);
|
|
88
|
+
const slide = shown?.getAttribute(CAROUSEL_SLIDE_ATTR) ?? '';
|
|
89
|
+
if (0 === slide.length || slide === lastSlide)
|
|
90
|
+
return;
|
|
91
|
+
lastSlide = slide;
|
|
92
|
+
send({ slide });
|
|
93
|
+
};
|
|
94
|
+
const slides = new MutationObserver(onSlide);
|
|
95
|
+
slides.observe(root, {
|
|
96
|
+
subtree: true,
|
|
97
|
+
attributes: true,
|
|
98
|
+
attributeFilter: ['data-active', 'hidden'],
|
|
99
|
+
});
|
|
76
100
|
doc.addEventListener('click', onPress, true);
|
|
77
|
-
const observer = new MutationObserver(
|
|
101
|
+
const observer = new MutationObserver((records) => {
|
|
102
|
+
onChange();
|
|
103
|
+
if (0 < records.length)
|
|
104
|
+
onSlide();
|
|
105
|
+
});
|
|
78
106
|
observer.observe(root, {
|
|
79
107
|
attributes: true,
|
|
80
|
-
attributeFilter: [MIN_ATTR, CHAT_ATTR, SETTINGS_ATTR, REPORT_ATTR],
|
|
108
|
+
attributeFilter: [MIN_ATTR, CHAT_ATTR, SETTINGS_ATTR, REPORT_ATTR, PAGE_OPEN_ATTR],
|
|
81
109
|
});
|
|
82
110
|
onChange();
|
|
83
111
|
return () => {
|
|
84
112
|
doc.removeEventListener('click', onPress, true);
|
|
85
113
|
observer.disconnect();
|
|
114
|
+
slides.disconnect();
|
|
86
115
|
};
|
|
87
116
|
}
|
|
@@ -6,14 +6,15 @@ const BODIES = {
|
|
|
6
6
|
'caret-down': '<path d="m19 9l-7 7l-7-7"/>',
|
|
7
7
|
check: '<path d="m5 13l4 4L19 7"/>',
|
|
8
8
|
remove: '<path d="m4.5 19.5l15-15m-15 0l15 15"/>',
|
|
9
|
-
pause: '<path d="
|
|
10
|
-
play: '<
|
|
11
|
-
stop: '<
|
|
9
|
+
pause: '<path d="M8 5v14M16 5v14"/>',
|
|
10
|
+
play: '<path d="M8 5.75v12.5L18 12 8 5.75Z"/>',
|
|
11
|
+
stop: '<rect x="6.5" y="6.5" width="11" height="11" rx="2"/>',
|
|
12
12
|
copy: '<path d="M8 7v8a2 2 0 0 0 2 2h6M8 7V5a2 2 0 0 1 2-2h4.586a1 1 0 0 1 .707.293l4.414 4.414a1 1 0 0 1 .293.707V15a2 2 0 0 1-2 2h-2M8 7H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-2"/>',
|
|
13
13
|
download: '<path d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/>',
|
|
14
14
|
message: '<path d="M8.625 9.75a.375.375 0 1 1-.75 0a.375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0a.375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0a.375.375 0 0 1 .75 0Zm0 0h-.375m-13.5 3.01c0 1.6 1.123 2.994 2.707 3.227c1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332a48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"/>',
|
|
15
15
|
gear: '<g><path d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87c.074.04.147.083.22.127c.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 0 1 0 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 0 1 0-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124c.072-.044.146-.087.22-.128c.332-.183.582-.495.644-.869l.214-1.281Z"/><path d="M15 12a3 3 0 1 1-6 0a3 3 0 0 1 6 0Z"/></g>',
|
|
16
16
|
layout: '<path d="M3.75 6A2.25 2.25 0 0 1 6 3.75h2.25A2.25 2.25 0 0 1 10.5 6v2.25a2.25 2.25 0 0 1-2.25 2.25H6a2.25 2.25 0 0 1-2.25-2.25V6Zm0 9.75A2.25 2.25 0 0 1 6 13.5h2.25a2.25 2.25 0 0 1 2.25 2.25V18a2.25 2.25 0 0 1-2.25 2.25H6A2.25 2.25 0 0 1 3.75 18v-2.25ZM13.5 6a2.25 2.25 0 0 1 2.25-2.25H18A2.25 2.25 0 0 1 20.25 6v2.25A2.25 2.25 0 0 1 18 10.5h-2.25a2.25 2.25 0 0 1-2.25-2.25V6Zm0 9.75a2.25 2.25 0 0 1 2.25-2.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-2.25A2.25 2.25 0 0 1 13.5 18v-2.25Z"/>',
|
|
17
|
+
notes: '<path d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75a2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15a2.25 2.25 0 0 1 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z"/>',
|
|
17
18
|
trash: '<path d="m19 7l-.867 12.142A2 2 0 0 1 16.138 21H7.862a2 2 0 0 1-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v3M4 7h16"/>',
|
|
18
19
|
help: '<path d="M8.228 9c.549-1.165 2.03-2 3.772-2c2.21 0 4 1.343 4 3c0 1.4-1.278 2.575-3.006 2.907c-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0"/>',
|
|
19
20
|
'caret-right': '<path d="m9 5l7 7l-7 7"/>',
|
|
@@ -13,6 +13,7 @@ export declare const PresenterIcon: {
|
|
|
13
13
|
readonly COPY: "copy";
|
|
14
14
|
readonly DOWNLOAD: "download";
|
|
15
15
|
readonly MESSAGE: "message";
|
|
16
|
+
readonly NOTES: "notes";
|
|
16
17
|
readonly GEAR: "gear";
|
|
17
18
|
readonly LAYOUT: "layout";
|
|
18
19
|
readonly TRASH: "trash";
|
|
@@ -30,6 +31,7 @@ export declare const PRESENTER_ICON_SIZE: {
|
|
|
30
31
|
readonly SEND: 14;
|
|
31
32
|
readonly MIN: 12;
|
|
32
33
|
readonly HELP: 12;
|
|
34
|
+
readonly NAV: 18;
|
|
33
35
|
readonly TOOLBAR: 18;
|
|
34
36
|
readonly FAB: 22;
|
|
35
37
|
};
|
|
@@ -13,6 +13,7 @@ export const PresenterIcon = {
|
|
|
13
13
|
COPY: 'copy',
|
|
14
14
|
DOWNLOAD: 'download',
|
|
15
15
|
MESSAGE: 'message',
|
|
16
|
+
NOTES: 'notes',
|
|
16
17
|
GEAR: 'gear',
|
|
17
18
|
LAYOUT: 'layout',
|
|
18
19
|
TRASH: 'trash',
|
|
@@ -29,6 +30,7 @@ export const PRESENTER_ICON_SIZE = {
|
|
|
29
30
|
SEND: 14,
|
|
30
31
|
MIN: 12,
|
|
31
32
|
HELP: 12,
|
|
33
|
+
NAV: 18,
|
|
32
34
|
TOOLBAR: 18,
|
|
33
35
|
FAB: 22,
|
|
34
36
|
};
|
|
@@ -7,7 +7,7 @@ export declare const ACCOUNT_MENU_ATTR = "data-reticle-account-menu";
|
|
|
7
7
|
export declare const ACCOUNT_SIGNOUT_ATTR = "data-reticle-account-signout";
|
|
8
8
|
export declare const ACCOUNT_TEXT: {
|
|
9
9
|
readonly SIGNED_OUT: "Sign in";
|
|
10
|
-
readonly SIGNIN_TITLE: "
|
|
10
|
+
readonly SIGNIN_TITLE: "Sign in through your browser. Also copies `reticle login`, for a terminal";
|
|
11
11
|
readonly SIGNIN_COMMAND: "reticle login";
|
|
12
12
|
readonly DASHBOARD_TITLE: "Open this project on the dashboard";
|
|
13
13
|
readonly SYNC_TITLE: "Push to the dashboard now, instead of waiting for the next sync";
|
|
@@ -19,9 +19,10 @@ export declare const ACCOUNT_TEXT: {
|
|
|
19
19
|
readonly DASHBOARD_ACTION: "Open dashboard";
|
|
20
20
|
readonly LINK_HINT: "Not linked — run `reticle link` to keep a record on the dashboard";
|
|
21
21
|
readonly LINK_COMMAND: "reticle link";
|
|
22
|
-
readonly SIGNOUT_ACTION: "
|
|
23
|
-
readonly SIGNOUT_TITLE: "
|
|
22
|
+
readonly SIGNOUT_ACTION: "Copy sign-out command";
|
|
23
|
+
readonly SIGNOUT_TITLE: "Copy `reticle logout` to run in your terminal";
|
|
24
24
|
readonly SIGNOUT_COMMAND: "reticle logout";
|
|
25
|
+
readonly SIGNOUT_COPY_FAILED: "Run reticle logout in terminal";
|
|
25
26
|
readonly PROJECT_LABEL: "Project";
|
|
26
27
|
readonly HOST_LABEL: "Host";
|
|
27
28
|
readonly VERDICTS_LABEL: "Verdicts";
|
|
@@ -37,4 +38,4 @@ export declare function accountInitials(org: string | undefined): string;
|
|
|
37
38
|
export declare function accountControlHtml(account: AccountState | undefined, details?: AccountDetails, offerSignIn?: boolean): string;
|
|
38
39
|
export declare function accountCapsuleHtml(account: AccountState | undefined, dashboardUrl?: string, offerSignIn?: boolean): string;
|
|
39
40
|
export declare function syncButtonHtml(dashboardUrl: string | undefined): string;
|
|
40
|
-
export declare function mountAccountControl(root: HTMLElement): () => void;
|
|
41
|
+
export declare function mountAccountControl(root: HTMLElement, onSignIn?: () => void): () => void;
|
|
@@ -8,7 +8,7 @@ export const ACCOUNT_MENU_ATTR = 'data-reticle-account-menu';
|
|
|
8
8
|
export const ACCOUNT_SIGNOUT_ATTR = 'data-reticle-account-signout';
|
|
9
9
|
export const ACCOUNT_TEXT = {
|
|
10
10
|
SIGNED_OUT: 'Sign in',
|
|
11
|
-
SIGNIN_TITLE: '
|
|
11
|
+
SIGNIN_TITLE: 'Sign in through your browser. Also copies `reticle login`, for a terminal',
|
|
12
12
|
SIGNIN_COMMAND: 'reticle login',
|
|
13
13
|
DASHBOARD_TITLE: 'Open this project on the dashboard',
|
|
14
14
|
SYNC_TITLE: 'Push to the dashboard now, instead of waiting for the next sync',
|
|
@@ -20,9 +20,10 @@ export const ACCOUNT_TEXT = {
|
|
|
20
20
|
DASHBOARD_ACTION: 'Open dashboard',
|
|
21
21
|
LINK_HINT: 'Not linked — run `reticle link` to keep a record on the dashboard',
|
|
22
22
|
LINK_COMMAND: 'reticle link',
|
|
23
|
-
SIGNOUT_ACTION: '
|
|
24
|
-
SIGNOUT_TITLE: '
|
|
23
|
+
SIGNOUT_ACTION: 'Copy sign-out command',
|
|
24
|
+
SIGNOUT_TITLE: 'Copy `reticle logout` to run in your terminal',
|
|
25
25
|
SIGNOUT_COMMAND: 'reticle logout',
|
|
26
|
+
SIGNOUT_COPY_FAILED: 'Run reticle logout in terminal',
|
|
26
27
|
PROJECT_LABEL: 'Project',
|
|
27
28
|
HOST_LABEL: 'Host',
|
|
28
29
|
VERDICTS_LABEL: 'Verdicts',
|
|
@@ -95,7 +96,7 @@ export function syncButtonHtml(dashboardUrl) {
|
|
|
95
96
|
return '';
|
|
96
97
|
return `<button type="button" class="reticle-sync-now" ${SYNC_BTN_ATTR} title="${ACCOUNT_TEXT.SYNC_TITLE}" aria-label="${ACCOUNT_TEXT.SYNC_TITLE}">${hiIconHtml(PresenterIcon.SYNC, PRESENTER_ICON_SIZE.HELP)}</button>`;
|
|
97
98
|
}
|
|
98
|
-
export function mountAccountControl(root) {
|
|
99
|
+
export function mountAccountControl(root, onSignIn) {
|
|
99
100
|
const controller = new AbortController();
|
|
100
101
|
const { signal } = controller;
|
|
101
102
|
const closeAll = (except) => {
|
|
@@ -111,14 +112,27 @@ export function mountAccountControl(root) {
|
|
|
111
112
|
trigger.setAttribute('aria-expanded', 'false');
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
|
-
const
|
|
115
|
+
const flashLabel = (el, value) => {
|
|
115
116
|
const label = el.querySelector('span') ?? el;
|
|
116
117
|
const previous = label.textContent;
|
|
117
|
-
label.textContent =
|
|
118
|
+
label.textContent = value;
|
|
118
119
|
setTimeout(() => {
|
|
119
120
|
label.textContent = previous;
|
|
120
121
|
}, ACCOUNT_COPIED_MS);
|
|
121
122
|
};
|
|
123
|
+
const copyCommand = async (command, el) => {
|
|
124
|
+
try {
|
|
125
|
+
if (navigator.clipboard === undefined)
|
|
126
|
+
throw new Error('Clipboard unavailable');
|
|
127
|
+
await navigator.clipboard.writeText(command);
|
|
128
|
+
flashLabel(el, ACCOUNT_TEXT.COPIED);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
flashLabel(el, command === ACCOUNT_TEXT.SIGNOUT_COMMAND
|
|
132
|
+
? ACCOUNT_TEXT.SIGNOUT_COPY_FAILED
|
|
133
|
+
: `Run ${command} in terminal`);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
122
136
|
root.addEventListener('click', (event) => {
|
|
123
137
|
const target = event.target;
|
|
124
138
|
if (!(target instanceof Element))
|
|
@@ -145,16 +159,15 @@ export function mountAccountControl(root) {
|
|
|
145
159
|
event.stopPropagation();
|
|
146
160
|
const command = copier.getAttribute('data-reticle-copy') ?? '';
|
|
147
161
|
if (command.length > 0)
|
|
148
|
-
void
|
|
149
|
-
flashCopied(copier);
|
|
162
|
+
void copyCommand(command, copier);
|
|
150
163
|
return;
|
|
151
164
|
}
|
|
152
165
|
const signin = target.closest(`[${ACCOUNT_SIGNIN_ATTR}]`);
|
|
153
166
|
if (signin instanceof HTMLElement) {
|
|
154
167
|
event.preventDefault();
|
|
155
168
|
event.stopPropagation();
|
|
156
|
-
|
|
157
|
-
|
|
169
|
+
onSignIn?.();
|
|
170
|
+
void copyCommand(ACCOUNT_TEXT.SIGNIN_COMMAND, signin);
|
|
158
171
|
return;
|
|
159
172
|
}
|
|
160
173
|
closeAll();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type AccountState, type HarnessConfig } from '@reticlehq/core';
|
|
2
|
+
import type { AnnotationItem } from '../review/annotator.js';
|
|
3
|
+
export type ChatView = 'activity' | 'flows' | 'annotations';
|
|
4
|
+
export declare function platformBase(config: HarnessConfig | undefined, account: AccountState): string;
|
|
5
|
+
export declare const CHAT_VIEWS_HTML = "\n <div data-reticle-harness-spot class=\"reticle-harness-spot\" hidden></div>";
|
|
6
|
+
export declare const FLOWS_PAGE_HTML: string;
|
|
7
|
+
export declare const CHAT_VIEWS_NAV_HTML: string;
|
|
8
|
+
export declare const ANNOTATIONS_HTML: string;
|
|
9
|
+
export declare const CHAT_VIEWS_CSS: string;
|
|
10
|
+
export declare class ChatViews {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(onHarness: (enabled: boolean) => void, onImpact: () => void, onOpenChat: (view: ChatView) => void);
|
|
13
|
+
mount(root: HTMLElement): void;
|
|
14
|
+
teardown(): void;
|
|
15
|
+
open(view: ChatView): void;
|
|
16
|
+
closePage(): void;
|
|
17
|
+
paintAccount(account: AccountState | undefined): void;
|
|
18
|
+
paintHarness(config: HarnessConfig | undefined): void;
|
|
19
|
+
paintImpact(verdicts: number): void;
|
|
20
|
+
paintAnnotations(items: readonly AnnotationItem[]): void;
|
|
21
|
+
}
|