@reticlehq/browser 3.6.0 → 3.7.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/action-report.d.ts +54 -0
- package/dist/actions/action-report.js +60 -0
- package/dist/actions/actions-dom.d.ts +1 -0
- package/dist/actions/actions-dom.js +12 -0
- package/dist/actions/actions-press.d.ts +1 -0
- package/dist/actions/actions-press.js +25 -1
- package/dist/actions/actions.d.ts +1 -37
- package/dist/actions/actions.js +24 -66
- package/dist/actions/appeared-text.js +3 -0
- package/dist/actions/danger-context.d.ts +2 -0
- package/dist/actions/danger-context.js +28 -2
- package/dist/actions/value-input.d.ts +1 -0
- package/dist/actions/value-input.js +11 -0
- package/dist/commands/commands.js +4 -0
- package/dist/dom/a11y.js +251 -10
- package/dist/dom/addressing/coverage-markers.d.ts +6 -0
- package/dist/dom/addressing/coverage-markers.js +13 -0
- package/dist/dom/dom-ignore.d.ts +2 -0
- package/dist/dom/dom-ignore.js +15 -2
- package/dist/dom/query.d.ts +1 -1
- package/dist/dom/query.js +78 -16
- package/dist/dom/render-page.d.ts +12 -0
- package/dist/dom/render-page.js +135 -0
- package/dist/dom/snapshot.js +55 -7
- package/dist/observers/dom.js +32 -16
- package/dist/observers/field.js +3 -21
- package/dist/observers/network.js +56 -7
- package/dist/observers/perf.js +53 -1
- package/dist/observers/route.js +6 -5
- package/dist/presenter/carousel/carousel.js +2 -7
- package/dist/presenter/carousel/panel-slides.d.ts +2 -4
- package/dist/presenter/carousel/panel-slides.js +17 -15
- package/dist/presenter/chrome/log-memory.d.ts +1 -0
- package/dist/presenter/chrome/presenter-log.d.ts +7 -0
- package/dist/presenter/chrome/presenter-log.js +48 -8
- package/dist/presenter/chrome/presenter-morph.d.ts +1 -0
- package/dist/presenter/chrome/presenter-morph.js +34 -0
- package/dist/presenter/chrome/presenter-report-copy.d.ts +17 -4
- package/dist/presenter/chrome/presenter-report-copy.js +26 -4
- package/dist/presenter/hud-telemetry.js +55 -4
- package/dist/presenter/presenter-account-styles.js +3 -3
- package/dist/presenter/presenter-account.d.ts +27 -5
- package/dist/presenter/presenter-account.js +83 -6
- package/dist/presenter/presenter-agent-link.d.ts +9 -0
- package/dist/presenter/presenter-agent-link.js +62 -0
- package/dist/presenter/presenter-chat-views.d.ts +27 -5
- package/dist/presenter/presenter-chat-views.js +312 -72
- package/dist/presenter/presenter-config.d.ts +2 -0
- package/dist/presenter/presenter-config.js +1 -0
- package/dist/presenter/presenter-controls.d.ts +0 -1
- package/dist/presenter/presenter-controls.js +13 -91
- package/dist/presenter/presenter-design-tokens.js +1 -1
- package/dist/presenter/presenter-frame.d.ts +1 -1
- package/dist/presenter/presenter-frame.js +8 -10
- package/dist/presenter/presenter-harness-row.d.ts +67 -0
- package/dist/presenter/presenter-harness-row.js +209 -0
- package/dist/presenter/presenter-personas.d.ts +35 -0
- package/dist/presenter/presenter-personas.js +95 -0
- package/dist/presenter/presenter-plan.js +25 -24
- package/dist/presenter/presenter-report-styles.js +40 -22
- package/dist/presenter/presenter-report.d.ts +2 -1
- package/dist/presenter/presenter-report.js +83 -17
- package/dist/presenter/presenter-settings-styles.js +8 -4
- package/dist/presenter/presenter-settings.d.ts +7 -6
- package/dist/presenter/presenter-settings.js +75 -34
- package/dist/presenter/presenter-shell-styles.js +12 -3
- package/dist/presenter/presenter-shell.d.ts +10 -4
- package/dist/presenter/presenter-shell.js +31 -23
- package/dist/presenter/presenter-styles.js +0 -2
- package/dist/presenter/presenter-workspace.js +10 -3
- package/dist/presenter/presenter.d.ts +3 -2
- package/dist/presenter/presenter.js +81 -20
- package/dist/registry/declared-platform.js +2 -0
- package/dist/reticle-inject.js +777 -700
- package/dist/reticle.js +36 -2
- package/dist/storage-keys.d.ts +3 -2
- package/dist/storage-keys.js +7 -3
- package/dist/transport/transport.js +5 -3
- package/dist/transport/unreachable-message.d.ts +1 -1
- package/dist/transport/unreachable-message.js +3 -5
- package/package.json +2 -2
- package/dist/presenter/carousel/offer-card.d.ts +0 -21
- package/dist/presenter/carousel/offer-card.js +0 -56
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { PERSONA_KEY_PREFIX } from '../storage-keys.js';
|
|
2
|
+
import { esc } from './chrome/presenter-safe-html.js';
|
|
3
|
+
export const CUSTOM_PERSONA = 'custom';
|
|
4
|
+
export const PERSONAS = [
|
|
5
|
+
{
|
|
6
|
+
id: 'first-time',
|
|
7
|
+
label: 'First-time visitor',
|
|
8
|
+
hint: 'starts from the first page, reads the labels and follows the obvious path',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: 'power-user',
|
|
12
|
+
label: 'Returning power user',
|
|
13
|
+
hint: 'goes straight to the main task, takes shortcuts and repeats it quickly',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'phone',
|
|
17
|
+
label: 'On a phone, slow connection',
|
|
18
|
+
hint: 'small-screen habits: taps, waits on loading, retries when nothing seems to happen',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'keyboard',
|
|
22
|
+
label: 'Keyboard only',
|
|
23
|
+
hint: 'Tab, Enter and Escape only: focus order, traps and controls it cannot reach',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'careless',
|
|
27
|
+
label: 'Careless user (bad and unexpected input)',
|
|
28
|
+
hint: 'empty fields, wrong formats, very long text, double submits, going back mid-flow',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'admin',
|
|
32
|
+
label: 'Admin / settings',
|
|
33
|
+
hint: 'changes settings and permissions, then checks they stick after a reload',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
export const DEFAULT_PERSONA = PERSONAS[0].id;
|
|
37
|
+
const TEXT = {
|
|
38
|
+
LABEL: 'As',
|
|
39
|
+
CUSTOM: 'Custom…',
|
|
40
|
+
CUSTOM_SHORT: 'Custom',
|
|
41
|
+
CUSTOM_HINT: 'Describe who to be or what to try, in your own words.',
|
|
42
|
+
CUSTOM_PLACEHOLDER: 'e.g. a first-time shopper paying by card',
|
|
43
|
+
};
|
|
44
|
+
export const PERSONA_PICK_ID = 'reticle-harness-persona-pick';
|
|
45
|
+
const PERSONA_TEXT_ID = 'reticle-harness-persona';
|
|
46
|
+
function presetOf(pick) {
|
|
47
|
+
return PERSONAS.find((persona) => persona.id === pick);
|
|
48
|
+
}
|
|
49
|
+
export function personaText(pick, custom) {
|
|
50
|
+
const preset = presetOf(pick);
|
|
51
|
+
if (preset !== undefined)
|
|
52
|
+
return `${preset.label}: ${preset.hint}`;
|
|
53
|
+
const own = custom.trim();
|
|
54
|
+
return 0 === own.length ? undefined : own;
|
|
55
|
+
}
|
|
56
|
+
export function personaLabel(pick) {
|
|
57
|
+
return presetOf(pick)?.label ?? TEXT.CUSTOM_SHORT;
|
|
58
|
+
}
|
|
59
|
+
export function personaPickHtml(pick, disabled = false) {
|
|
60
|
+
const options = [
|
|
61
|
+
...PERSONAS.map((p) => ({ id: p.id, label: p.label, hint: p.hint })),
|
|
62
|
+
{ id: CUSTOM_PERSONA, label: TEXT.CUSTOM, hint: TEXT.CUSTOM_HINT },
|
|
63
|
+
]
|
|
64
|
+
.map((o) => `<option value="${o.id}" title="${esc(o.hint)}"${o.id === pick ? ' selected' : ''}>${esc(o.label)}</option>`)
|
|
65
|
+
.join('');
|
|
66
|
+
const hint = esc(presetOf(pick)?.hint ?? TEXT.CUSTOM_HINT);
|
|
67
|
+
return (`<label class="reticle-harness-as" for="${PERSONA_PICK_ID}">${TEXT.LABEL}</label>` +
|
|
68
|
+
`<select id="${PERSONA_PICK_ID}" data-reticle-harness-persona-pick class="reticle-harness-persona" title="${hint}" aria-describedby="${PERSONA_PICK_ID}-hint"${disabled ? ' disabled' : ''}>${options}</select>` +
|
|
69
|
+
`<span id="${PERSONA_PICK_ID}-hint" class="reticle-sr">${hint}</span>`);
|
|
70
|
+
}
|
|
71
|
+
export function personaCustomHtml(pick, disabled = false) {
|
|
72
|
+
return CUSTOM_PERSONA === pick
|
|
73
|
+
? `<input type="text" id="${PERSONA_TEXT_ID}" data-reticle-harness-persona class="reticle-harness-persona" aria-label="${TEXT.CUSTOM_HINT}" placeholder="${TEXT.CUSTOM_PLACEHOLDER}"${disabled ? ' disabled' : ''}>`
|
|
74
|
+
: '';
|
|
75
|
+
}
|
|
76
|
+
export function knownPick(value) {
|
|
77
|
+
return value !== null && value !== undefined && (CUSTOM_PERSONA === value || presetOf(value))
|
|
78
|
+
? value
|
|
79
|
+
: undefined;
|
|
80
|
+
}
|
|
81
|
+
export function readPick(projectId) {
|
|
82
|
+
try {
|
|
83
|
+
return (knownPick(localStorage.getItem(`${PERSONA_KEY_PREFIX}${projectId ?? ''}`)) ?? DEFAULT_PERSONA);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return DEFAULT_PERSONA;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function savePick(projectId, pick) {
|
|
90
|
+
try {
|
|
91
|
+
localStorage.setItem(`${PERSONA_KEY_PREFIX}${projectId ?? ''}`, pick);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -17,32 +17,33 @@ const GLYPH = {
|
|
|
17
17
|
[ScriptStatus.FAILED]: '✗',
|
|
18
18
|
[ScriptStatus.BLOCKED]: '⊘',
|
|
19
19
|
[ScriptStatus.NOT_TAKEN]: '–',
|
|
20
|
+
[ScriptStatus.UNDECIDED]: '?',
|
|
20
21
|
};
|
|
21
22
|
export const PLAN_CSS = `
|
|
22
|
-
[data-reticle-
|
|
23
|
-
[data-reticle-
|
|
24
|
-
[data-reticle-
|
|
25
|
-
[data-reticle-
|
|
26
|
-
[data-reticle-
|
|
27
|
-
[data-reticle-
|
|
28
|
-
[data-reticle-
|
|
29
|
-
[data-reticle-
|
|
30
|
-
[data-reticle-
|
|
31
|
-
[data-reticle-
|
|
32
|
-
[data-reticle-
|
|
33
|
-
[data-reticle-
|
|
34
|
-
[data-reticle-
|
|
35
|
-
[data-reticle-
|
|
36
|
-
[data-reticle-
|
|
37
|
-
[data-reticle-
|
|
38
|
-
[data-reticle-
|
|
39
|
-
[data-reticle-
|
|
40
|
-
[data-reticle-
|
|
41
|
-
[data-reticle-
|
|
42
|
-
[data-reticle-
|
|
43
|
-
[data-reticle-
|
|
44
|
-
[data-reticle-
|
|
45
|
-
[data-reticle-
|
|
23
|
+
[data-reticle-page-panel="harness"] .reticle-plan{flex:none;margin:0 10px 8px;padding:8px 10px;border:1px solid var(--reticle-hud-border);border-radius:10px;background:rgba(255,255,255,.03);}
|
|
24
|
+
[data-reticle-page-panel="harness"] .reticle-plan[hidden]{display:none;}
|
|
25
|
+
[data-reticle-page-panel="harness"] .reticle-plan-head{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:var(--reticle-hud-size-xs);color:var(--reticle-hud-text-muted);}
|
|
26
|
+
[data-reticle-page-panel="harness"] .reticle-plan-head strong{color:var(--reticle-hud-text);font-size:var(--reticle-hud-size-sm);font-weight:600;}
|
|
27
|
+
[data-reticle-page-panel="harness"] .reticle-plan-head span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
28
|
+
[data-reticle-page-panel="harness"] .reticle-plan-close{flex:none;border:0;background:none;color:inherit;cursor:pointer;font-size:14px;line-height:1;padding:2px 4px;}
|
|
29
|
+
[data-reticle-page-panel="harness"] .reticle-plan-lanes{display:flex;flex-direction:column;gap:6px;max-height:240px;overflow:auto;scrollbar-width:none;}
|
|
30
|
+
[data-reticle-page-panel="harness"] .reticle-plan-lanes::-webkit-scrollbar{display:none;}
|
|
31
|
+
[data-reticle-page-panel="harness"] .reticle-plan-lane{display:flex;gap:6px;align-items:flex-start;min-width:0;}
|
|
32
|
+
[data-reticle-page-panel="harness"] .reticle-plan-lane-name{flex:none;width:16px;padding-top:6px;font-size:11px;font-weight:600;text-align:center;color:var(--reticle-hud-text-muted);}
|
|
33
|
+
[data-reticle-page-panel="harness"] .reticle-plan-lane-journeys{display:flex;flex:1;min-width:0;flex-direction:column;gap:4px;}
|
|
34
|
+
[data-reticle-page-panel="harness"] .reticle-plan-journey{display:block;width:100%;text-align:left;border:1px solid transparent;border-radius:8px;padding:5px 7px;background:rgba(255,255,255,.04);color:var(--reticle-hud-text);font:inherit;font-size:var(--reticle-hud-size-xs);cursor:pointer;}
|
|
35
|
+
[data-reticle-page-panel="harness"] .reticle-plan-journey[data-status="running"]{border-color:var(--reticle-c-active);box-shadow:0 0 12px -4px var(--reticle-c-active);}
|
|
36
|
+
[data-reticle-page-panel="harness"] .reticle-plan-journey[data-status="blocked"],[data-reticle-page-panel="harness"] .reticle-plan-journey[data-status="not-taken"]{opacity:.55;}
|
|
37
|
+
[data-reticle-page-panel="harness"] .reticle-plan-row{display:flex;gap:6px;align-items:baseline;min-width:0;}
|
|
38
|
+
[data-reticle-page-panel="harness"] .reticle-plan-row b{flex:1;min-width:0;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
39
|
+
[data-reticle-page-panel="harness"] .reticle-plan-glyph{flex:none;width:12px;text-align:center;}
|
|
40
|
+
[data-reticle-page-panel="harness"] [data-status="running"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-page-panel="harness"] .reticle-plan-step[data-status="running"]>.reticle-plan-glyph{color:var(--reticle-c-active);animation:reticle-flow-pulse 1.2s ease-in-out infinite;}
|
|
41
|
+
[data-reticle-page-panel="harness"] [data-status="passed"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-page-panel="harness"] .reticle-plan-step[data-status="passed"]>.reticle-plan-glyph{color:#4ade80;}
|
|
42
|
+
[data-reticle-page-panel="harness"] [data-status="failed"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-page-panel="harness"] .reticle-plan-step[data-status="failed"]>.reticle-plan-glyph{color:#f87171;}
|
|
43
|
+
[data-reticle-page-panel="harness"] .reticle-plan-meta{display:block;margin:2px 0 0 18px;color:var(--reticle-hud-text-muted);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
44
|
+
[data-reticle-page-panel="harness"] .reticle-plan-steps{margin:4px 0 0 18px;display:flex;flex-direction:column;gap:2px;}
|
|
45
|
+
[data-reticle-page-panel="harness"] .reticle-plan-step{display:flex;gap:6px;color:var(--reticle-hud-text-muted);font-size:11px;min-width:0;}
|
|
46
|
+
[data-reticle-page-panel="harness"] .reticle-plan-step span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
46
47
|
`;
|
|
47
48
|
const STATUSES = new Set(Object.values(ScriptStatus));
|
|
48
49
|
function statusOf(value) {
|
|
@@ -26,17 +26,17 @@ export const REPORT_CSS = `
|
|
|
26
26
|
[${REPORT_PANEL_ATTR}] .reticle-report-scope{
|
|
27
27
|
margin-left:auto;padding:3px 9px;border-radius:999px;cursor:pointer;
|
|
28
28
|
border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.04);
|
|
29
|
-
color:var(--reticle-muted);font:inherit;font-size:
|
|
29
|
+
color:var(--reticle-muted);font:inherit;font-size:11px;}
|
|
30
30
|
[${REPORT_PANEL_ATTR}] .reticle-report-scope:hover{background:rgba(255,255,255,.08);color:var(--reticle-fg);}
|
|
31
31
|
[${REPORT_PANEL_ATTR}] .reticle-report-close{
|
|
32
32
|
flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
|
|
33
33
|
border:none;background:transparent;color:var(--reticle-faint);cursor:pointer;line-height:0;}
|
|
34
34
|
[${REPORT_PANEL_ATTR}] .reticle-report-close svg{display:block;fill:none;stroke:currentColor;stroke-width:1.6;}
|
|
35
35
|
[${REPORT_PANEL_ATTR}] .reticle-report-body{
|
|
36
|
-
min-height:0;overflow-y:auto;padding:12px 14px 6px;
|
|
36
|
+
flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:12px 14px 6px;
|
|
37
37
|
scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent;}
|
|
38
38
|
[${REPORT_PANEL_ATTR}] .reticle-report-empty{
|
|
39
|
-
margin:0;padding:22px 6px;text-align:center;color:var(--reticle-faint);font-size:
|
|
39
|
+
margin:0;padding:22px 6px;text-align:center;color:var(--reticle-faint);font-size:12px;}
|
|
40
40
|
/* The streak sits above the hero, as a flame and a number: it is the one stat that is about
|
|
41
41
|
TODAY, so it reads first and never competes with the count it sits over. */
|
|
42
42
|
[${REPORT_PANEL_ATTR}] .reticle-report-streak{
|
|
@@ -45,19 +45,36 @@ export const REPORT_CSS = `
|
|
|
45
45
|
border:1px solid color-mix(in srgb,var(--reticle-c-active) 22%,transparent);
|
|
46
46
|
font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;}
|
|
47
47
|
[${REPORT_PANEL_ATTR}] .reticle-report-streak-label{
|
|
48
|
-
color:var(--reticle-faint);font-size:
|
|
48
|
+
color:var(--reticle-faint);font-size:11px;font-weight:400;}
|
|
49
49
|
[${REPORT_PANEL_ATTR}] .reticle-report-hero{display:flex;flex-direction:column;gap:2px;margin-bottom:10px;}
|
|
50
50
|
[${REPORT_PANEL_ATTR}] .reticle-report-hero-value{
|
|
51
51
|
font-size:34px;font-weight:700;line-height:1;letter-spacing:-.02em;color:var(--reticle-c-active);}
|
|
52
|
-
[${REPORT_PANEL_ATTR}] .reticle-report-hero-label{color:var(--reticle-muted);font-size:
|
|
52
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-hero-label{color:var(--reticle-muted);font-size:12px;}
|
|
53
53
|
[${REPORT_PANEL_ATTR}] .reticle-report-verdicts{display:flex;gap:6px;margin-bottom:12px;}
|
|
54
54
|
[${REPORT_PANEL_ATTR}] .reticle-sync-status{font-size:11px;color:var(--reticle-faint);font-variant-numeric:tabular-nums;white-space:nowrap;}
|
|
55
55
|
[${REPORT_PANEL_ATTR}] .reticle-sync-status[data-reticle-sync-status="refused"]{color:var(--reticle-c-error,#f87171);}
|
|
56
56
|
[${REPORT_PANEL_ATTR}] .reticle-report-coverage{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin-bottom:12px;padding:8px 10px;border:1px solid var(--reticle-hud-border);border-radius:var(--reticle-hud-radius-sm,8px);}
|
|
57
57
|
[${REPORT_PANEL_ATTR}] .reticle-report-coverage-value{font-size:18px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--reticle-hud-text);}
|
|
58
58
|
[${REPORT_PANEL_ATTR}] .reticle-report-coverage-levels{display:flex;flex-wrap:wrap;gap:4px 10px;width:100%;font-size:11px;color:var(--reticle-faint);font-variant-numeric:tabular-nums;}
|
|
59
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-instrumentation{margin-bottom:12px;padding:10px;border:1px solid var(--reticle-hud-border);border-radius:var(--reticle-hud-radius-md);}
|
|
60
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-instrumentation-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;}
|
|
61
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-instrumentation-head .reticle-report-section{margin-bottom:0;}
|
|
62
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-instrumentation-value{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--reticle-hud-text);}
|
|
63
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-caps{display:grid;grid-template-columns:1fr 1fr;gap:4px 10px;margin:8px 0 0;padding:0;list-style:none;}
|
|
64
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 6px;min-width:0;font-size:11px;line-height:1.4;color:var(--reticle-muted);}
|
|
65
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap-mark{flex:none;width:10px;text-align:center;}
|
|
66
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap-name{flex:1;min-width:0;}
|
|
67
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap[data-state="seen"] .reticle-report-cap-mark{color:#86efac;}
|
|
68
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap[data-state="missing"]{grid-column:1/-1;color:var(--reticle-hud-text);}
|
|
69
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap[data-state="missing"] .reticle-report-cap-mark{color:#fca5a5;}
|
|
70
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap[data-state="unseen"]{color:var(--reticle-faint);}
|
|
71
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-cap-cost{flex-basis:100%;padding-left:16px;color:var(--reticle-faint);}
|
|
72
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-caps-note{display:block;margin-top:6px;color:var(--reticle-faint);font-size:11px;}
|
|
73
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-copy-prompt{display:block;width:100%;margin-top:10px;padding:6px 10px;border:1px solid color-mix(in srgb,var(--reticle-hud-brand) 50%,transparent);
|
|
74
|
+
border-radius:var(--reticle-hud-radius-sm);background:var(--reticle-hud-brand-soft);color:var(--reticle-hud-brand);font:inherit;font-size:12px;font-weight:600;cursor:pointer;}
|
|
75
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-copy-prompt:hover{filter:brightness(1.15);}
|
|
59
76
|
[${REPORT_PANEL_ATTR}] .reticle-report-verdict{
|
|
60
|
-
flex:1;padding:5px 8px;border-radius:8px;font-size:
|
|
77
|
+
flex:1;padding:5px 8px;border-radius:8px;font-size:11px;text-align:center;
|
|
61
78
|
background:rgba(255,255,255,.05);color:var(--reticle-muted);}
|
|
62
79
|
[${REPORT_PANEL_ATTR}] .reticle-report-verdict[data-kind="fail"]{color:#fca5a5;}
|
|
63
80
|
[${REPORT_PANEL_ATTR}] .reticle-report-verdict[data-kind="unknown"]{color:#fcd34d;}
|
|
@@ -67,11 +84,11 @@ export const REPORT_CSS = `
|
|
|
67
84
|
display:flex;flex-direction:column;gap:2px;padding:8px;border-radius:10px;
|
|
68
85
|
background:rgba(255,255,255,.04);}
|
|
69
86
|
[${REPORT_PANEL_ATTR}] .reticle-report-value{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;}
|
|
70
|
-
[${REPORT_PANEL_ATTR}] .reticle-report-label{color:var(--reticle-faint);font-size:
|
|
87
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-label{color:var(--reticle-faint);font-size:11px;line-height:1.3;}
|
|
71
88
|
/* An estimate is labelled as one, and its label carries what it is measured against. */
|
|
72
89
|
[${REPORT_PANEL_ATTR}] .reticle-report-basis{
|
|
73
90
|
display:block;margin-top:2px;color:var(--reticle-c-active);opacity:.8;
|
|
74
|
-
font-size:
|
|
91
|
+
font-size:11px;letter-spacing:.06em;text-transform:uppercase;cursor:help;}
|
|
75
92
|
[${REPORT_PANEL_ATTR}] .reticle-report-defects-wrap{margin-top:14px;}
|
|
76
93
|
/* The heading and its push control on one line, so the button reads as belonging to this section
|
|
77
94
|
rather than floating above the list. */
|
|
@@ -87,9 +104,9 @@ export const REPORT_CSS = `
|
|
|
87
104
|
[${REPORT_PANEL_ATTR}] .reticle-report-defect-title{
|
|
88
105
|
font-size:11px;line-height:1.35;overflow-wrap:anywhere;}
|
|
89
106
|
[${REPORT_PANEL_ATTR}] .reticle-report-defect-detail{
|
|
90
|
-
color:var(--reticle-faint);font-size:
|
|
107
|
+
color:var(--reticle-faint);font-size:11px;line-height:1.35;overflow-wrap:anywhere;}
|
|
91
108
|
[${REPORT_PANEL_ATTR}] .reticle-report-defect-source{
|
|
92
|
-
color:var(--reticle-faint);font-size:
|
|
109
|
+
color:var(--reticle-faint);font-size:11px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
|
|
93
110
|
overflow-wrap:anywhere;}
|
|
94
111
|
.reticle-report-defect-link{flex:none;display:inline-flex;align-items:center;justify-content:center;
|
|
95
112
|
width:20px;height:20px;border-radius:6px;color:var(--reticle-faint);pointer-events:auto;
|
|
@@ -98,19 +115,19 @@ export const REPORT_CSS = `
|
|
|
98
115
|
.reticle-report-defect-link:focus-visible{opacity:1;}
|
|
99
116
|
.reticle-report-defect-link:hover{color:var(--reticle-fg);background:rgba(255,255,255,.07);}
|
|
100
117
|
[${REPORT_PANEL_ATTR}] .reticle-report-defects-more{
|
|
101
|
-
display:inline-block;margin-top:8px;font-size:
|
|
118
|
+
display:inline-block;margin-top:8px;font-size:11px;color:var(--reticle-c-active);
|
|
102
119
|
text-decoration:none;}
|
|
103
120
|
[${REPORT_PANEL_ATTR}] .reticle-report-defects-more:hover{text-decoration:underline;}
|
|
104
|
-
[${REPORT_PANEL_ATTR}] .reticle-report-defects-all{display:inline-block;margin-top:8px;border:0;padding:0;background:none;cursor:pointer;font:inherit;font-size:
|
|
121
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-defects-all{display:inline-block;margin-top:8px;border:0;padding:0;background:none;cursor:pointer;font:inherit;font-size:11px;font-weight:500;color:var(--reticle-c-active);}
|
|
105
122
|
[${REPORT_PANEL_ATTR}] .reticle-report-defects-all:hover{text-decoration:underline;}
|
|
106
123
|
[${REPORT_PANEL_ATTR}] .reticle-report-local-only{
|
|
107
124
|
margin:14px 0 0;padding-top:10px;border-top:1px solid var(--reticle-line);
|
|
108
|
-
color:var(--reticle-faint);font-size:
|
|
125
|
+
color:var(--reticle-faint);font-size:11px;line-height:1.45;}
|
|
109
126
|
[${REPORT_PANEL_ATTR}] .reticle-report-local-only code{
|
|
110
127
|
font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--reticle-c-active);}
|
|
111
128
|
[${REPORT_PANEL_ATTR}] .reticle-report-chart-wrap{margin-top:12px;}
|
|
112
129
|
[${REPORT_PANEL_ATTR}] .reticle-report-section{
|
|
113
|
-
display:block;margin-bottom:6px;color:var(--reticle-faint);font-size:
|
|
130
|
+
display:block;margin-bottom:6px;color:var(--reticle-faint);font-size:11px;
|
|
114
131
|
letter-spacing:.06em;text-transform:uppercase;}
|
|
115
132
|
/* Thirty fixed slots, not a flex row: one recorded day is one thin bar on a month's axis, and a
|
|
116
133
|
single stretched block would read as "a month of solid work" on the day you install it. */
|
|
@@ -120,19 +137,20 @@ export const REPORT_CSS = `
|
|
|
120
137
|
min-width:2px;border-radius:2px 2px 0 0;
|
|
121
138
|
background:color-mix(in srgb,var(--reticle-c-active) 55%,transparent);}
|
|
122
139
|
[${REPORT_PANEL_ATTR}] .reticle-report-bar[data-hot="1"]{background:#f87171;}
|
|
140
|
+
/* Sharing is a quiet row under the record, never the loudest thing on the panel. */
|
|
123
141
|
[${REPORT_PANEL_ATTR}] .reticle-report-foot{
|
|
124
|
-
flex:none;display:flex;flex-wrap:
|
|
142
|
+
flex:none;display:flex;flex-wrap:nowrap;align-items:center;gap:2px;padding:6px 10px 2px 14px;
|
|
125
143
|
border-top:1px solid rgba(255,255,255,.06);}
|
|
144
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-share-label{margin-right:4px;color:var(--reticle-faint);font-size:11px;}
|
|
126
145
|
[${REPORT_PANEL_ATTR}] .reticle-report-share{
|
|
127
|
-
padding:
|
|
128
|
-
|
|
129
|
-
[${REPORT_PANEL_ATTR}] .reticle-report-share:hover{background:rgba(255,255,255,.
|
|
130
|
-
[${REPORT_PANEL_ATTR}] .reticle-report-refer{
|
|
131
|
-
border-color:color-mix(in srgb,var(--reticle-c-active) 45%,transparent);color:var(--reticle-fg);}
|
|
146
|
+
flex:none;padding:3px 6px;border:0;border-radius:6px;cursor:pointer;font:inherit;font-size:11px;
|
|
147
|
+
background:transparent;color:var(--reticle-muted);white-space:nowrap;}
|
|
148
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-share:hover{background:rgba(255,255,255,.08);color:var(--reticle-fg);}
|
|
149
|
+
[${REPORT_PANEL_ATTR}] .reticle-report-refer{margin-left:auto;color:var(--reticle-hud-brand);}
|
|
132
150
|
[${REPORT_PANEL_ATTR}] .reticle-report-links{
|
|
133
|
-
flex:none;display:flex;gap:12px;padding:
|
|
151
|
+
flex:none;display:flex;gap:12px;padding:2px 14px 10px;}
|
|
134
152
|
[${REPORT_PANEL_ATTR}] .reticle-report-links a{
|
|
135
|
-
color:var(--reticle-faint);font-size:
|
|
153
|
+
color:var(--reticle-faint);font-size:11px;text-decoration:none;}
|
|
136
154
|
[${REPORT_PANEL_ATTR}] .reticle-report-links a:hover{color:var(--reticle-fg);text-decoration:underline;}
|
|
137
155
|
|
|
138
156
|
/* Who this record belongs to, and the push-now control. Tokens only — no literal colours. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AccountState, type ImpactScope, type ImpactSnapshot } from '@reticlehq/core';
|
|
2
2
|
export declare function reportPanelHtml(): string;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function instrumentationHtml(instrumentation: Readonly<Record<string, unknown>> | undefined): string;
|
|
4
|
+
export declare function reportBodyHtml(scope: ImpactScope, dashboardUrl?: string, account?: AccountState, projectName?: string, coverage?: Readonly<Record<string, number>>, sync?: Readonly<Record<string, unknown>>, instrumentation?: Readonly<Record<string, unknown>>): string;
|
|
4
5
|
interface ReportHost {
|
|
5
6
|
onBeforeOpen?: () => void;
|
|
6
7
|
onSyncNow?: () => void;
|
|
@@ -4,7 +4,7 @@ import { HUD_SURFACE_CLASS } from './chrome/presenter-hud-chrome.js';
|
|
|
4
4
|
import { esc, isSafeDashboardUrl } from './chrome/presenter-safe-html.js';
|
|
5
5
|
import { ACCOUNT_SIGNIN_ATTR, ACCOUNT_TEXT, SYNC_BTN_ATTR, accountControlHtml, syncButtonHtml, } from './presenter-account.js';
|
|
6
6
|
import { REPORT_PANEL_ATTR, REPORT_ATTR, REPORT_CLOSE_ATTR } from './presenter-config.js';
|
|
7
|
-
import { REPORT_LINKS, REPORT_TEXT, buildLinkedInShareUrl, buildReferralText, buildShareText, buildXShareUrl, compactDuration, compactNumber, COVERAGE_LEVELS, } from './chrome/presenter-report-copy.js';
|
|
7
|
+
import { REPORT_LINKS, REPORT_TEXT, buildLinkedInShareUrl, buildReferralText, buildShareText, buildXShareUrl, compactDuration, compactNumber, COVERAGE_LEVELS, CAPABILITY_WORDS, } from './chrome/presenter-report-copy.js';
|
|
8
8
|
const SCOPE_ATTR = 'data-reticle-report-scope';
|
|
9
9
|
const SCOPE = { PROJECT: 'project', MACHINE: 'machine' };
|
|
10
10
|
const SHARE_X_ATTR = 'data-reticle-share-x';
|
|
@@ -22,9 +22,10 @@ export function reportPanelHtml() {
|
|
|
22
22
|
<button type="button" ${REPORT_CLOSE_ATTR} class="reticle-report-close" title="Close" aria-label="Close impact">${close}</button>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="reticle-report-body" data-reticle-report-body></div>
|
|
25
|
-
<div class="reticle-report-foot">
|
|
26
|
-
<
|
|
27
|
-
<button type="button" ${
|
|
25
|
+
<div class="reticle-report-foot" role="group" aria-label="${REPORT_TEXT.SHARE_LABEL}">
|
|
26
|
+
<span class="reticle-report-share-label">${REPORT_TEXT.SHARE_LABEL}</span>
|
|
27
|
+
<button type="button" ${SHARE_X_ATTR} class="reticle-report-share">${REPORT_TEXT.POST_X}</button>
|
|
28
|
+
<button type="button" ${SHARE_IN_ATTR} class="reticle-report-share">${REPORT_TEXT.POST_IN}</button>
|
|
28
29
|
<button type="button" ${SHARE_COPY_ATTR} class="reticle-report-share">${REPORT_TEXT.COPY}</button>
|
|
29
30
|
<button type="button" ${REFER_ATTR} class="reticle-report-share reticle-report-refer">${REPORT_TEXT.REFER}</button>
|
|
30
31
|
</div>
|
|
@@ -91,18 +92,76 @@ function syncStatusHtml(sync) {
|
|
|
91
92
|
return '';
|
|
92
93
|
const num = (key) => ('number' === typeof sync[key] ? sync[key] : 0);
|
|
93
94
|
const status = sync['status'];
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
const keyRefused = 'string' === typeof sync['keyRefused'] ? sync['keyRefused'] : undefined;
|
|
96
|
+
const label = keyRefused !== undefined
|
|
97
|
+
? REPORT_TEXT.KEY_REFUSED
|
|
98
|
+
: 'refused' === status
|
|
99
|
+
? `${String(num('refused'))} refused`
|
|
100
|
+
: 'pending' === status
|
|
101
|
+
? `${String(num('pending'))} waiting`
|
|
102
|
+
: 'on-platform' === status
|
|
103
|
+
? `Synced · ${String(num('onPlatform'))}`
|
|
104
|
+
: 'local-only' === status
|
|
105
|
+
? `${String(num('pending'))} ${REPORT_TEXT.NOT_SENT}`
|
|
106
|
+
: undefined;
|
|
101
107
|
if (label === undefined)
|
|
102
108
|
return '';
|
|
103
|
-
const said =
|
|
104
|
-
|
|
109
|
+
const said = keyRefused !== undefined
|
|
110
|
+
? keyRefused
|
|
111
|
+
: 'local-only' === status
|
|
112
|
+
? REPORT_TEXT.NOT_SENT_HELP
|
|
113
|
+
: 'string' === typeof sync['said']
|
|
114
|
+
? sync['said']
|
|
115
|
+
: '';
|
|
116
|
+
const runUrl = sync['runUrl'];
|
|
117
|
+
const seeRun = 'string' === typeof runUrl && isSafeDashboardUrl(runUrl)
|
|
118
|
+
? ` <a class="reticle-sync-run" data-reticle-link="run" href="${esc(runUrl)}" target="_blank" rel="noreferrer noopener">${REPORT_TEXT.SEE_RUN}</a>`
|
|
119
|
+
: '';
|
|
120
|
+
return `<span class="reticle-sync-status" data-reticle-sync-status="${esc(String(status))}" title="${esc(said)}">${label}</span>${seeRun}`;
|
|
121
|
+
}
|
|
122
|
+
const capabilityWords = (name) => 'string' === typeof name ? esc(CAPABILITY_WORDS[name] ?? name) : undefined;
|
|
123
|
+
function capabilityItem(state, name, cost = '') {
|
|
124
|
+
const mark = 'seen' === state ? '✓' : 'missing' === state ? '✕' : '○';
|
|
125
|
+
const why = '' === cost ? '' : `<span class="reticle-report-cap-cost">${cost}</span>`;
|
|
126
|
+
return `<li class="reticle-report-cap" data-state="${state}"><span class="reticle-report-cap-mark" aria-hidden="true">${mark}</span><span class="reticle-report-cap-name">${name}</span>${why}</li>`;
|
|
127
|
+
}
|
|
128
|
+
export function instrumentationHtml(instrumentation) {
|
|
129
|
+
if (instrumentation === undefined)
|
|
130
|
+
return '';
|
|
131
|
+
const covered = instrumentation['covered'];
|
|
132
|
+
const total = instrumentation['total'];
|
|
133
|
+
if ('number' !== typeof covered || 'number' !== typeof total)
|
|
134
|
+
return '';
|
|
135
|
+
const list = (key) => {
|
|
136
|
+
const value = instrumentation[key];
|
|
137
|
+
return Array.isArray(value) ? value : [];
|
|
138
|
+
};
|
|
139
|
+
const seen = list('seen').flatMap((n) => {
|
|
140
|
+
const name = capabilityWords(n);
|
|
141
|
+
return name === undefined ? [] : [capabilityItem('seen', name)];
|
|
142
|
+
});
|
|
143
|
+
const missing = list('missing').flatMap((m) => {
|
|
144
|
+
if ('object' !== typeof m || null === m)
|
|
145
|
+
return [];
|
|
146
|
+
const gap = m;
|
|
147
|
+
const name = capabilityWords(gap['capability']);
|
|
148
|
+
const cost = 'string' === typeof gap['cost'] ? esc(gap['cost']) : '';
|
|
149
|
+
return name === undefined ? [] : [capabilityItem('missing', name, cost)];
|
|
150
|
+
});
|
|
151
|
+
const unseen = list('notSeenYet').flatMap((n) => {
|
|
152
|
+
const name = capabilityWords(n);
|
|
153
|
+
return name === undefined ? [] : [capabilityItem('unseen', name)];
|
|
154
|
+
});
|
|
155
|
+
const items = [...missing, ...seen, ...unseen];
|
|
156
|
+
const caps = 0 === items.length
|
|
157
|
+
? ''
|
|
158
|
+
: `<ul class="reticle-report-caps">${items.join('')}</ul>${0 === unseen.length ? '' : `<span class="reticle-report-caps-note">○ ${REPORT_TEXT.NOT_SEEN_YET}</span>`}`;
|
|
159
|
+
const copy = 'string' === typeof instrumentation['prompt']
|
|
160
|
+
? `<button type="button" class="reticle-report-copy-prompt" ${COPY_PROMPT_ATTR}>${REPORT_TEXT.COPY_PROMPT}</button>`
|
|
161
|
+
: '';
|
|
162
|
+
return `<div class="reticle-report-instrumentation" title="${REPORT_TEXT.INSTRUMENTATION_HELP}"><div class="reticle-report-instrumentation-head"><span class="reticle-report-section">${REPORT_TEXT.INSTRUMENTATION}</span><span class="reticle-report-instrumentation-value">${REPORT_TEXT.covered(Math.round(covered), Math.round(total))}</span></div>${caps}${copy}</div>`;
|
|
105
163
|
}
|
|
164
|
+
const COPY_PROMPT_ATTR = 'data-reticle-copy-prompt';
|
|
106
165
|
function coverageHtml(coverage) {
|
|
107
166
|
if (coverage === undefined)
|
|
108
167
|
return '';
|
|
@@ -116,14 +175,14 @@ function coverageHtml(coverage) {
|
|
|
116
175
|
.join('');
|
|
117
176
|
return `<div class="reticle-report-coverage" title="${REPORT_TEXT.COVERAGE_HELP}"><span class="reticle-report-section">${REPORT_TEXT.COVERAGE}</span><span class="reticle-report-coverage-value">${head}</span><div class="reticle-report-coverage-levels">${rows}</div></div>`;
|
|
118
177
|
}
|
|
119
|
-
export function reportBodyHtml(scope, dashboardUrl, account, projectName, coverage, sync) {
|
|
178
|
+
export function reportBodyHtml(scope, dashboardUrl, account, projectName, coverage, sync, instrumentation) {
|
|
120
179
|
const c = scope.counts;
|
|
121
180
|
if (0 === c.calls)
|
|
122
181
|
return `<p class="reticle-report-empty">${REPORT_TEXT.EMPTY}</p>`;
|
|
123
182
|
const streak = scope.records.streakDays > 0
|
|
124
183
|
? `<span class="reticle-report-streak" title="Consecutive days with at least one verdict">🔥 ${String(scope.records.streakDays)} <span class="reticle-report-streak-label">${REPORT_TEXT.STREAK}</span></span>`
|
|
125
184
|
: '';
|
|
126
|
-
const hero = `<div class="reticle-report-hero"><span class="reticle-report-hero-value">${compactNumber(c.failed)}</span><span class="reticle-report-hero-label">${REPORT_TEXT.
|
|
185
|
+
const hero = `<div class="reticle-report-hero"><span class="reticle-report-hero-value">${compactNumber(c.failed)}</span><span class="reticle-report-hero-label">${REPORT_TEXT.heroDefects(c.failed)}</span></div>`;
|
|
127
186
|
const verdicts = `<div class="reticle-report-verdicts" title="${REPORT_TEXT.UNKNOWN_HELP}">
|
|
128
187
|
<span class="reticle-report-verdict" data-kind="pass">${compactNumber(c.passed)} ${REPORT_TEXT.PASSED}</span>
|
|
129
188
|
<span class="reticle-report-verdict" data-kind="fail">${compactNumber(c.failed)} ${REPORT_TEXT.FAILED}</span>
|
|
@@ -140,7 +199,7 @@ export function reportBodyHtml(scope, dashboardUrl, account, projectName, covera
|
|
|
140
199
|
card(compactDuration(scope.savings.minutes.value * 60_000), REPORT_TEXT.SAVED_MINUTES, scope.savings.minutes.basis),
|
|
141
200
|
].join('');
|
|
142
201
|
const identity = `<div class="reticle-report-identity">${accountControlHtml(account, { dashboardUrl, projectName, verdicts: c.verdicts, defects: c.failed })}${syncButtonHtml(dashboardUrl)}${syncStatusHtml(sync)}</div>`;
|
|
143
|
-
return `<div class="reticle-report-top">${streak}${identity}</div>${hero}${verdicts}${coverageHtml(coverage)}<div class="reticle-report-grid">${cards}</div>${defects(scope, dashboardUrl)}${chart(scope)}${localOnly(scope, dashboardUrl, account)}`;
|
|
202
|
+
return `<div class="reticle-report-top">${streak}${identity}</div>${hero}${verdicts}${instrumentationHtml(instrumentation)}${coverageHtml(coverage)}<div class="reticle-report-grid">${cards}</div>${defects(scope, dashboardUrl)}${chart(scope)}${localOnly(scope, dashboardUrl, account)}`;
|
|
144
203
|
}
|
|
145
204
|
function localOnly(scope, dashboardUrl, account) {
|
|
146
205
|
if (dashboardUrl !== undefined)
|
|
@@ -212,6 +271,13 @@ export class PresenterReport {
|
|
|
212
271
|
void this.#copy(ACCOUNT_TEXT.SIGNIN_COMMAND, signin);
|
|
213
272
|
return;
|
|
214
273
|
}
|
|
274
|
+
const copyPrompt = target.closest(`[${COPY_PROMPT_ATTR}]`);
|
|
275
|
+
const prompt = this.#snapshot?.instrumentation?.['prompt'];
|
|
276
|
+
if (copyPrompt !== null && 'string' === typeof prompt) {
|
|
277
|
+
e.stopPropagation();
|
|
278
|
+
void this.#copy(prompt, copyPrompt);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
215
281
|
const sync = target.closest(`[${SYNC_BTN_ATTR}]`);
|
|
216
282
|
if (sync !== null) {
|
|
217
283
|
e.stopPropagation();
|
|
@@ -274,7 +340,7 @@ export class PresenterReport {
|
|
|
274
340
|
this.#body.innerHTML =
|
|
275
341
|
scope === undefined
|
|
276
342
|
? `<p class="reticle-report-empty">${REPORT_TEXT.EMPTY}</p>`
|
|
277
|
-
: reportBodyHtml(scope, this.#snapshot?.dashboardUrl, this.#snapshot?.account, this.#snapshot?.projectName, this.#global ? undefined : this.#snapshot?.coverage, this.#global ? undefined : this.#snapshot?.sync);
|
|
343
|
+
: reportBodyHtml(scope, this.#snapshot?.dashboardUrl, this.#snapshot?.account, this.#snapshot?.projectName, this.#global ? undefined : this.#snapshot?.coverage, this.#global ? undefined : this.#snapshot?.sync, this.#global ? undefined : this.#snapshot?.instrumentation);
|
|
278
344
|
}
|
|
279
345
|
#openShare(url) {
|
|
280
346
|
window.open(url, '_blank', 'noopener,noreferrer');
|
|
@@ -56,8 +56,10 @@ export const SETTINGS_CSS = `
|
|
|
56
56
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-row{
|
|
57
57
|
display:flex;align-items:center;justify-content:space-between;gap:12px;
|
|
58
58
|
padding:8px 14px;min-height:30px;}
|
|
59
|
+
[${SETTINGS_PANEL_ATTR}] .reticle-settings-labelcol{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px;}
|
|
59
60
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-label{
|
|
60
|
-
display:inline-flex;align-items:center;gap:6px;color:rgba(255,255,255,.
|
|
61
|
+
display:inline-flex;align-items:center;gap:6px;color:rgba(255,255,255,.86);font-size:13px;font-weight:500;}
|
|
62
|
+
[${SETTINGS_PANEL_ATTR}] .reticle-settings-desc{color:rgba(255,255,255,.5);font-size:11px;line-height:1.35;}
|
|
61
63
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-help{
|
|
62
64
|
display:inline-flex;align-items:center;justify-content:center;
|
|
63
65
|
width:14px;height:14px;border:none;border-radius:999px;padding:0;cursor:help;
|
|
@@ -86,7 +88,7 @@ export const SETTINGS_CSS = `
|
|
|
86
88
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-toggle:focus-visible{outline:2px solid rgba(59,130,246,.55);outline-offset:2px;}
|
|
87
89
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-row[data-disabled="1"]{opacity:.45;pointer-events:none;}
|
|
88
90
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-section{
|
|
89
|
-
padding:10px 14px 6px;color:rgba(255,255,255,.38);font-size:
|
|
91
|
+
padding:10px 14px 6px;color:rgba(255,255,255,.38);font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;}
|
|
90
92
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-swatches{
|
|
91
93
|
display:flex;gap:8px;flex-wrap:wrap;padding:0 14px 10px;}
|
|
92
94
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-swatch{
|
|
@@ -98,13 +100,13 @@ export const SETTINGS_CSS = `
|
|
|
98
100
|
border-color:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.35);}
|
|
99
101
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-swatch:focus-visible{outline:2px solid rgba(59,130,246,.65);outline-offset:2px;}
|
|
100
102
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-checkrow{
|
|
101
|
-
display:flex;align-items:center;gap:10px;padding:7px 14px;color:rgba(255,255,255,.
|
|
103
|
+
display:flex;align-items:center;gap:10px;padding:7px 14px;color:rgba(255,255,255,.86);font-size:13px;
|
|
102
104
|
cursor:pointer;user-select:none;margin:0;transition:background .12s;}
|
|
103
105
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-checkrow:hover{background:rgba(255,255,255,.03);}
|
|
104
106
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-check{
|
|
105
107
|
width:16px;height:16px;border-radius:5px;border:1px solid rgba(255,255,255,.22);
|
|
106
108
|
background:rgba(255,255,255,.04);display:inline-flex;align-items:center;justify-content:center;
|
|
107
|
-
color:transparent;font-size:
|
|
109
|
+
color:transparent;font-size:11px;line-height:1;flex:none;transition:background .12s,border-color .12s,color .12s;}
|
|
108
110
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-check[data-on="1"]{
|
|
109
111
|
background:#fafafa;border-color:#fafafa;color:#111;}
|
|
110
112
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-check:focus-visible{outline:2px solid rgba(59,130,246,.55);outline-offset:2px;}
|
|
@@ -135,6 +137,8 @@ export const SETTINGS_CSS = `
|
|
|
135
137
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-kill[data-armed="1"]{background:#ef4444;border-color:#ef4444;color:#fff;}
|
|
136
138
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-kill:focus-visible{outline:2px solid rgba(239,68,68,.6);outline-offset:2px;}
|
|
137
139
|
[${SETTINGS_PANEL_ATTR}] .reticle-settings-kill-sub{margin:8px 0 0;font-size:11px;line-height:1.45;color:rgba(255,255,255,.55);}
|
|
140
|
+
/* The SDK version line sits straight in the foot, so it takes the rows' inset rather than none. */
|
|
141
|
+
[${SETTINGS_PANEL_ATTR}] .reticle-settings-foot > .reticle-settings-kill-sub{padding:0 14px;}
|
|
138
142
|
[${'data-reticle-overlay'}][${SETTINGS_ATTR}="1"] [${'data-reticle-hud'}] .reticle-tb-tip{
|
|
139
143
|
opacity:0;visibility:hidden;transition-delay:0s;}
|
|
140
144
|
/* The dock's accent IS the theme's active colour, published as --reticle-accent on the overlay by
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { HarnessConfig } from '@reticlehq/core';
|
|
2
|
+
import type { HarnessGateView } from './presenter-harness-row.js';
|
|
2
3
|
import { SETTINGS_CSS } from './presenter-settings-styles.js';
|
|
4
|
+
import { type Credits } from '@reticlehq/core/hud';
|
|
3
5
|
import type { AccountState } from '@reticlehq/core';
|
|
4
6
|
import { type AccountDetails } from './presenter-account.js';
|
|
5
7
|
export { SETTINGS_CSS };
|
|
@@ -41,12 +43,11 @@ export interface PresenterSettings {
|
|
|
41
43
|
export declare function getPresenterSettings(): PresenterSettings;
|
|
42
44
|
export declare function loadPresenterSettings(): PresenterSettings;
|
|
43
45
|
export declare const SETTINGS_ACCOUNT_ATTR = "data-reticle-settings-account";
|
|
44
|
-
export declare
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} | undefined): string;
|
|
48
|
-
export declare function paintHarnessRow(root: ParentNode, config: HarnessConfig | undefined): void;
|
|
46
|
+
export declare const HARNESS_LOCKED_HELP = "The Harness is not available to this workspace right now: see Plan in your Reticle dashboard.";
|
|
47
|
+
export declare function creditsLeft(credits: Credits | undefined): string;
|
|
48
|
+
export declare function paintHarnessRow(root: ParentNode, config: HarnessConfig | undefined, gate?: HarnessGateView): void;
|
|
49
49
|
export declare function paintSettingsAccount(root: HTMLElement, account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
|
|
50
|
+
export declare function paintSdkVersion(root: ParentNode, version: string | undefined): void;
|
|
50
51
|
export declare function settingsPanelHtml(): string;
|
|
51
52
|
export interface SettingsHost {
|
|
52
53
|
onHideUntilRestart?: () => void;
|
|
@@ -62,7 +63,7 @@ export declare class PresenterSettingsPanel {
|
|
|
62
63
|
constructor(host?: SettingsHost);
|
|
63
64
|
contains(node: Node): boolean;
|
|
64
65
|
mount(root: HTMLElement): void;
|
|
65
|
-
paintHarness(config: HarnessConfig | undefined): void;
|
|
66
|
+
paintHarness(config: HarnessConfig | undefined, gate?: HarnessGateView): void;
|
|
66
67
|
teardown(): void;
|
|
67
68
|
isOpen(): boolean;
|
|
68
69
|
open(): void;
|