@reticlehq/browser 3.6.0 → 3.8.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.
Files changed (129) hide show
  1. package/dist/actions/action-report.d.ts +64 -0
  2. package/dist/actions/action-report.js +87 -0
  3. package/dist/actions/actions-dom.d.ts +5 -0
  4. package/dist/actions/actions-dom.js +32 -4
  5. package/dist/actions/actions-press.d.ts +1 -0
  6. package/dist/actions/actions-press.js +25 -1
  7. package/dist/actions/actions.d.ts +2 -37
  8. package/dist/actions/actions.js +56 -80
  9. package/dist/actions/appeared-text.js +5 -2
  10. package/dist/actions/click-target.d.ts +1 -0
  11. package/dist/actions/click-target.js +14 -0
  12. package/dist/actions/danger-context.d.ts +4 -1
  13. package/dist/actions/danger-context.js +45 -4
  14. package/dist/actions/value-input.d.ts +1 -0
  15. package/dist/actions/value-input.js +11 -0
  16. package/dist/activate.d.ts +14 -0
  17. package/dist/activate.js +43 -0
  18. package/dist/busy.d.ts +3 -0
  19. package/dist/busy.js +42 -0
  20. package/dist/commands/commands.js +49 -17
  21. package/dist/connect-options.d.ts +12 -1
  22. package/dist/connect-options.js +18 -1
  23. package/dist/dom/a11y.d.ts +2 -0
  24. package/dist/dom/a11y.js +353 -80
  25. package/dist/dom/addressing/coverage-markers.d.ts +6 -0
  26. package/dist/dom/addressing/coverage-markers.js +13 -0
  27. package/dist/dom/chart.d.ts +3 -2
  28. package/dist/dom/chart.js +3 -2
  29. package/dist/dom/dom-ignore.d.ts +8 -0
  30. package/dist/dom/dom-ignore.js +57 -2
  31. package/dist/dom/layout-audit.d.ts +15 -0
  32. package/dist/dom/layout-audit.js +208 -0
  33. package/dist/dom/paint-context.d.ts +15 -0
  34. package/dist/dom/paint-context.js +78 -0
  35. package/dist/dom/query.d.ts +2 -1
  36. package/dist/dom/query.js +163 -38
  37. package/dist/dom/render-page.d.ts +12 -0
  38. package/dist/dom/render-page.js +135 -0
  39. package/dist/dom/shadow-registry.d.ts +1 -0
  40. package/dist/dom/shadow-registry.js +27 -0
  41. package/dist/dom/snapshot.d.ts +5 -0
  42. package/dist/dom/snapshot.js +135 -36
  43. package/dist/dom/stable-selector.d.ts +1 -0
  44. package/dist/dom/stable-selector.js +19 -0
  45. package/dist/dom/text-match.d.ts +12 -0
  46. package/dist/dom/text-match.js +115 -0
  47. package/dist/dom/theme.d.ts +1 -0
  48. package/dist/dom/theme.js +21 -9
  49. package/dist/dom/virtualized.js +5 -1
  50. package/dist/index.d.ts +2 -1
  51. package/dist/index.js +5 -0
  52. package/dist/observers/blind-spots.js +3 -2
  53. package/dist/observers/canvas.d.ts +18 -0
  54. package/dist/observers/canvas.js +76 -0
  55. package/dist/observers/dom.js +96 -32
  56. package/dist/observers/field.d.ts +11 -0
  57. package/dist/observers/field.js +116 -30
  58. package/dist/observers/install-all.js +4 -0
  59. package/dist/observers/media.d.ts +2 -0
  60. package/dist/observers/media.js +32 -0
  61. package/dist/observers/net-detail/network-body.d.ts +2 -0
  62. package/dist/observers/net-detail/network-body.js +8 -1
  63. package/dist/observers/network.js +82 -13
  64. package/dist/observers/perf.js +53 -1
  65. package/dist/observers/route.d.ts +2 -0
  66. package/dist/observers/route.js +39 -9
  67. package/dist/presenter/carousel/carousel.js +2 -7
  68. package/dist/presenter/carousel/panel-slides.d.ts +2 -4
  69. package/dist/presenter/carousel/panel-slides.js +17 -15
  70. package/dist/presenter/chrome/log-memory.d.ts +1 -0
  71. package/dist/presenter/chrome/presenter-log.d.ts +7 -0
  72. package/dist/presenter/chrome/presenter-log.js +48 -8
  73. package/dist/presenter/chrome/presenter-morph.d.ts +1 -0
  74. package/dist/presenter/chrome/presenter-morph.js +34 -0
  75. package/dist/presenter/chrome/presenter-report-copy.d.ts +12 -4
  76. package/dist/presenter/chrome/presenter-report-copy.js +12 -4
  77. package/dist/presenter/hud-telemetry.js +55 -4
  78. package/dist/presenter/presenter-account-styles.js +3 -3
  79. package/dist/presenter/presenter-account.d.ts +27 -5
  80. package/dist/presenter/presenter-account.js +83 -6
  81. package/dist/presenter/presenter-agent-link.d.ts +9 -0
  82. package/dist/presenter/presenter-agent-link.js +62 -0
  83. package/dist/presenter/presenter-chat-views.d.ts +25 -4
  84. package/dist/presenter/presenter-chat-views.js +339 -72
  85. package/dist/presenter/presenter-config.d.ts +3 -0
  86. package/dist/presenter/presenter-config.js +2 -0
  87. package/dist/presenter/presenter-controls.d.ts +0 -1
  88. package/dist/presenter/presenter-controls.js +13 -91
  89. package/dist/presenter/presenter-design-tokens.js +1 -1
  90. package/dist/presenter/presenter-frame.d.ts +3 -2
  91. package/dist/presenter/presenter-frame.js +31 -24
  92. package/dist/presenter/presenter-harness-row.d.ts +56 -0
  93. package/dist/presenter/presenter-harness-row.js +170 -0
  94. package/dist/presenter/presenter-personas.d.ts +35 -0
  95. package/dist/presenter/presenter-personas.js +95 -0
  96. package/dist/presenter/presenter-plan.js +25 -24
  97. package/dist/presenter/presenter-report-styles.js +23 -22
  98. package/dist/presenter/presenter-report.js +29 -13
  99. package/dist/presenter/presenter-run-state.js +2 -1
  100. package/dist/presenter/presenter-settings-styles.js +8 -4
  101. package/dist/presenter/presenter-settings.d.ts +4 -4
  102. package/dist/presenter/presenter-settings.js +66 -28
  103. package/dist/presenter/presenter-shell-styles.js +12 -3
  104. package/dist/presenter/presenter-shell.d.ts +11 -3
  105. package/dist/presenter/presenter-shell.js +60 -22
  106. package/dist/presenter/presenter-styles.js +0 -2
  107. package/dist/presenter/presenter-workspace.js +10 -3
  108. package/dist/presenter/presenter.d.ts +3 -2
  109. package/dist/presenter/presenter.js +107 -25
  110. package/dist/registry/declared-platform.js +2 -0
  111. package/dist/registry/store-adapters.d.ts +5 -2
  112. package/dist/registry/store-adapters.js +40 -10
  113. package/dist/reticle-inject.js +771 -703
  114. package/dist/reticle.d.ts +4 -2
  115. package/dist/reticle.js +72 -8
  116. package/dist/security/page-location.d.ts +2 -0
  117. package/dist/security/page-location.js +7 -0
  118. package/dist/security/serialization.js +1 -1
  119. package/dist/storage-keys.d.ts +4 -2
  120. package/dist/storage-keys.js +8 -3
  121. package/dist/timers/native/native-timers.d.ts +1 -0
  122. package/dist/timers/native/native-timers.js +5 -0
  123. package/dist/transport/transport.d.ts +1 -0
  124. package/dist/transport/transport.js +23 -3
  125. package/dist/transport/unreachable-message.d.ts +1 -1
  126. package/dist/transport/unreachable-message.js +3 -5
  127. package/package.json +6 -2
  128. package/dist/presenter/carousel/offer-card.d.ts +0 -21
  129. package/dist/presenter/carousel/offer-card.js +0 -56
@@ -0,0 +1,35 @@
1
+ export declare const CUSTOM_PERSONA = "custom";
2
+ export declare const PERSONAS: readonly [{
3
+ readonly id: "first-time";
4
+ readonly label: "First-time visitor";
5
+ readonly hint: "starts from the first page, reads the labels and follows the obvious path";
6
+ }, {
7
+ readonly id: "power-user";
8
+ readonly label: "Returning power user";
9
+ readonly hint: "goes straight to the main task, takes shortcuts and repeats it quickly";
10
+ }, {
11
+ readonly id: "phone";
12
+ readonly label: "On a phone, slow connection";
13
+ readonly hint: "small-screen habits: taps, waits on loading, retries when nothing seems to happen";
14
+ }, {
15
+ readonly id: "keyboard";
16
+ readonly label: "Keyboard only";
17
+ readonly hint: "Tab, Enter and Escape only: focus order, traps and controls it cannot reach";
18
+ }, {
19
+ readonly id: "careless";
20
+ readonly label: "Careless user (bad and unexpected input)";
21
+ readonly hint: "empty fields, wrong formats, very long text, double submits, going back mid-flow";
22
+ }, {
23
+ readonly id: "admin";
24
+ readonly label: "Admin / settings";
25
+ readonly hint: "changes settings and permissions, then checks they stick after a reload";
26
+ }];
27
+ export declare const DEFAULT_PERSONA: "first-time";
28
+ export declare const PERSONA_PICK_ID = "reticle-harness-persona-pick";
29
+ export declare function personaText(pick: string, custom: string): string | undefined;
30
+ export declare function personaLabel(pick: string): string;
31
+ export declare function personaPickHtml(pick: string, disabled?: boolean): string;
32
+ export declare function personaCustomHtml(pick: string, disabled?: boolean): string;
33
+ export declare function knownPick(value: string | null | undefined): string | undefined;
34
+ export declare function readPick(projectId: string | undefined): string;
35
+ export declare function savePick(projectId: string | undefined, pick: string): void;
@@ -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-chat-panel] .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);}
23
- [data-reticle-chat-panel] .reticle-plan[hidden]{display:none;}
24
- [data-reticle-chat-panel] .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);}
25
- [data-reticle-chat-panel] .reticle-plan-head strong{color:var(--reticle-hud-text);font-size:var(--reticle-hud-size-sm);font-weight:600;}
26
- [data-reticle-chat-panel] .reticle-plan-head span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
27
- [data-reticle-chat-panel] .reticle-plan-close{flex:none;border:0;background:none;color:inherit;cursor:pointer;font-size:14px;line-height:1;padding:2px 4px;}
28
- [data-reticle-chat-panel] .reticle-plan-lanes{display:flex;flex-direction:column;gap:6px;max-height:240px;overflow:auto;scrollbar-width:none;}
29
- [data-reticle-chat-panel] .reticle-plan-lanes::-webkit-scrollbar{display:none;}
30
- [data-reticle-chat-panel] .reticle-plan-lane{display:flex;gap:6px;align-items:flex-start;min-width:0;}
31
- [data-reticle-chat-panel] .reticle-plan-lane-name{flex:none;width:16px;padding-top:6px;font-size:10px;font-weight:600;text-align:center;color:var(--reticle-hud-text-muted);}
32
- [data-reticle-chat-panel] .reticle-plan-lane-journeys{display:flex;flex:1;min-width:0;flex-direction:column;gap:4px;}
33
- [data-reticle-chat-panel] .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;}
34
- [data-reticle-chat-panel] .reticle-plan-journey[data-status="running"]{border-color:var(--reticle-c-active);box-shadow:0 0 12px -4px var(--reticle-c-active);}
35
- [data-reticle-chat-panel] .reticle-plan-journey[data-status="blocked"],[data-reticle-chat-panel] .reticle-plan-journey[data-status="not-taken"]{opacity:.55;}
36
- [data-reticle-chat-panel] .reticle-plan-row{display:flex;gap:6px;align-items:baseline;min-width:0;}
37
- [data-reticle-chat-panel] .reticle-plan-row b{flex:1;min-width:0;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
38
- [data-reticle-chat-panel] .reticle-plan-glyph{flex:none;width:12px;text-align:center;}
39
- [data-reticle-chat-panel] [data-status="running"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-chat-panel] .reticle-plan-step[data-status="running"]>.reticle-plan-glyph{color:var(--reticle-c-active);animation:reticle-flow-pulse 1.2s ease-in-out infinite;}
40
- [data-reticle-chat-panel] [data-status="passed"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-chat-panel] .reticle-plan-step[data-status="passed"]>.reticle-plan-glyph{color:#4ade80;}
41
- [data-reticle-chat-panel] [data-status="failed"]>.reticle-plan-row>.reticle-plan-glyph,[data-reticle-chat-panel] .reticle-plan-step[data-status="failed"]>.reticle-plan-glyph{color:#f87171;}
42
- [data-reticle-chat-panel] .reticle-plan-meta{display:block;margin:2px 0 0 18px;color:var(--reticle-hud-text-muted);font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
43
- [data-reticle-chat-panel] .reticle-plan-steps{margin:4px 0 0 18px;display:flex;flex-direction:column;gap:2px;}
44
- [data-reticle-chat-panel] .reticle-plan-step{display:flex;gap:6px;color:var(--reticle-hud-text-muted);font-size:10px;min-width:0;}
45
- [data-reticle-chat-panel] .reticle-plan-step span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
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:10.5px;}
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:11.5px;}
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,11 +45,11 @@ 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:9.5px;font-weight:400;letter-spacing:.04em;text-transform:uppercase;}
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:11.5px;}
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);}
@@ -57,7 +57,7 @@ export const REPORT_CSS = `
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
59
  [${REPORT_PANEL_ATTR}] .reticle-report-verdict{
60
- flex:1;padding:5px 8px;border-radius:8px;font-size:10.5px;text-align:center;
60
+ flex:1;padding:5px 8px;border-radius:8px;font-size:11px;text-align:center;
61
61
  background:rgba(255,255,255,.05);color:var(--reticle-muted);}
62
62
  [${REPORT_PANEL_ATTR}] .reticle-report-verdict[data-kind="fail"]{color:#fca5a5;}
63
63
  [${REPORT_PANEL_ATTR}] .reticle-report-verdict[data-kind="unknown"]{color:#fcd34d;}
@@ -67,11 +67,11 @@ export const REPORT_CSS = `
67
67
  display:flex;flex-direction:column;gap:2px;padding:8px;border-radius:10px;
68
68
  background:rgba(255,255,255,.04);}
69
69
  [${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:9.5px;line-height:1.3;}
70
+ [${REPORT_PANEL_ATTR}] .reticle-report-label{color:var(--reticle-faint);font-size:11px;line-height:1.3;}
71
71
  /* An estimate is labelled as one, and its label carries what it is measured against. */
72
72
  [${REPORT_PANEL_ATTR}] .reticle-report-basis{
73
73
  display:block;margin-top:2px;color:var(--reticle-c-active);opacity:.8;
74
- font-size:8.5px;letter-spacing:.06em;text-transform:uppercase;cursor:help;}
74
+ font-size:11px;letter-spacing:.06em;text-transform:uppercase;cursor:help;}
75
75
  [${REPORT_PANEL_ATTR}] .reticle-report-defects-wrap{margin-top:14px;}
76
76
  /* The heading and its push control on one line, so the button reads as belonging to this section
77
77
  rather than floating above the list. */
@@ -87,9 +87,9 @@ export const REPORT_CSS = `
87
87
  [${REPORT_PANEL_ATTR}] .reticle-report-defect-title{
88
88
  font-size:11px;line-height:1.35;overflow-wrap:anywhere;}
89
89
  [${REPORT_PANEL_ATTR}] .reticle-report-defect-detail{
90
- color:var(--reticle-faint);font-size:10px;line-height:1.35;overflow-wrap:anywhere;}
90
+ color:var(--reticle-faint);font-size:11px;line-height:1.35;overflow-wrap:anywhere;}
91
91
  [${REPORT_PANEL_ATTR}] .reticle-report-defect-source{
92
- color:var(--reticle-faint);font-size:9.5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
92
+ color:var(--reticle-faint);font-size:11px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
93
93
  overflow-wrap:anywhere;}
94
94
  .reticle-report-defect-link{flex:none;display:inline-flex;align-items:center;justify-content:center;
95
95
  width:20px;height:20px;border-radius:6px;color:var(--reticle-faint);pointer-events:auto;
@@ -98,19 +98,19 @@ export const REPORT_CSS = `
98
98
  .reticle-report-defect-link:focus-visible{opacity:1;}
99
99
  .reticle-report-defect-link:hover{color:var(--reticle-fg);background:rgba(255,255,255,.07);}
100
100
  [${REPORT_PANEL_ATTR}] .reticle-report-defects-more{
101
- display:inline-block;margin-top:8px;font-size:10px;color:var(--reticle-c-active);
101
+ display:inline-block;margin-top:8px;font-size:11px;color:var(--reticle-c-active);
102
102
  text-decoration:none;}
103
103
  [${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:10.5px;font-weight:500;color:var(--reticle-c-active);}
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:11px;font-weight:500;color:var(--reticle-c-active);}
105
105
  [${REPORT_PANEL_ATTR}] .reticle-report-defects-all:hover{text-decoration:underline;}
106
106
  [${REPORT_PANEL_ATTR}] .reticle-report-local-only{
107
107
  margin:14px 0 0;padding-top:10px;border-top:1px solid var(--reticle-line);
108
- color:var(--reticle-faint);font-size:10px;line-height:1.45;}
108
+ color:var(--reticle-faint);font-size:11px;line-height:1.45;}
109
109
  [${REPORT_PANEL_ATTR}] .reticle-report-local-only code{
110
110
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--reticle-c-active);}
111
111
  [${REPORT_PANEL_ATTR}] .reticle-report-chart-wrap{margin-top:12px;}
112
112
  [${REPORT_PANEL_ATTR}] .reticle-report-section{
113
- display:block;margin-bottom:6px;color:var(--reticle-faint);font-size:9.5px;
113
+ display:block;margin-bottom:6px;color:var(--reticle-faint);font-size:11px;
114
114
  letter-spacing:.06em;text-transform:uppercase;}
115
115
  /* Thirty fixed slots, not a flex row: one recorded day is one thin bar on a month's axis, and a
116
116
  single stretched block would read as "a month of solid work" on the day you install it. */
@@ -120,19 +120,20 @@ export const REPORT_CSS = `
120
120
  min-width:2px;border-radius:2px 2px 0 0;
121
121
  background:color-mix(in srgb,var(--reticle-c-active) 55%,transparent);}
122
122
  [${REPORT_PANEL_ATTR}] .reticle-report-bar[data-hot="1"]{background:#f87171;}
123
+ /* Sharing is a quiet row under the record, never the loudest thing on the panel. */
123
124
  [${REPORT_PANEL_ATTR}] .reticle-report-foot{
124
- flex:none;display:flex;flex-wrap:wrap;gap:6px;padding:10px 14px 8px;
125
+ flex:none;display:flex;flex-wrap:nowrap;align-items:center;gap:2px;padding:6px 10px 2px 14px;
125
126
  border-top:1px solid rgba(255,255,255,.06);}
127
+ [${REPORT_PANEL_ATTR}] .reticle-report-share-label{margin-right:4px;color:var(--reticle-faint);font-size:11px;}
126
128
  [${REPORT_PANEL_ATTR}] .reticle-report-share{
127
- padding:5px 10px;border-radius:8px;cursor:pointer;font:inherit;font-size:11px;
128
- border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.04);color:var(--reticle-muted);}
129
- [${REPORT_PANEL_ATTR}] .reticle-report-share:hover{background:rgba(255,255,255,.09);color:var(--reticle-fg);}
130
- [${REPORT_PANEL_ATTR}] .reticle-report-refer{
131
- border-color:color-mix(in srgb,var(--reticle-c-active) 45%,transparent);color:var(--reticle-fg);}
129
+ flex:none;padding:3px 6px;border:0;border-radius:6px;cursor:pointer;font:inherit;font-size:11px;
130
+ background:transparent;color:var(--reticle-muted);white-space:nowrap;}
131
+ [${REPORT_PANEL_ATTR}] .reticle-report-share:hover{background:rgba(255,255,255,.08);color:var(--reticle-fg);}
132
+ [${REPORT_PANEL_ATTR}] .reticle-report-refer{margin-left:auto;color:var(--reticle-hud-brand);}
132
133
  [${REPORT_PANEL_ATTR}] .reticle-report-links{
133
- flex:none;display:flex;gap:12px;padding:0 14px 12px;}
134
+ flex:none;display:flex;gap:12px;padding:2px 14px 10px;}
134
135
  [${REPORT_PANEL_ATTR}] .reticle-report-links a{
135
- color:var(--reticle-faint);font-size:10.5px;text-decoration:none;}
136
+ color:var(--reticle-faint);font-size:11px;text-decoration:none;}
136
137
  [${REPORT_PANEL_ATTR}] .reticle-report-links a:hover{color:var(--reticle-fg);text-decoration:underline;}
137
138
 
138
139
  /* Who this record belongs to, and the push-now control. Tokens only — no literal colours. */
@@ -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
- <button type="button" ${SHARE_X_ATTR} class="reticle-report-share">Post on X</button>
27
- <button type="button" ${SHARE_IN_ATTR} class="reticle-report-share">LinkedIn</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,17 +92,32 @@ 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 label = 'refused' === status
95
- ? `${String(num('refused'))} refused`
96
- : 'pending' === status
97
- ? `${String(num('pending'))} waiting`
98
- : 'on-platform' === status
99
- ? `Synced · ${String(num('onPlatform'))}`
100
- : undefined;
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 = 'string' === typeof sync['said'] ? sync['said'] : '';
104
- return `<span class="reticle-sync-status" data-reticle-sync-status="${status}" title="${esc(said)}">${label}</span>`;
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}`;
105
121
  }
106
122
  function coverageHtml(coverage) {
107
123
  if (coverage === undefined)
@@ -123,7 +139,7 @@ export function reportBodyHtml(scope, dashboardUrl, account, projectName, covera
123
139
  const streak = scope.records.streakDays > 0
124
140
  ? `<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
141
  : '';
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.HERO_DEFECTS}</span></div>`;
142
+ 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
143
  const verdicts = `<div class="reticle-report-verdicts" title="${REPORT_TEXT.UNKNOWN_HELP}">
128
144
  <span class="reticle-report-verdict" data-kind="pass">${compactNumber(c.passed)} ${REPORT_TEXT.PASSED}</span>
129
145
  <span class="reticle-report-verdict" data-kind="fail">${compactNumber(c.failed)} ${REPORT_TEXT.FAILED}</span>
@@ -1,4 +1,5 @@
1
1
  import { SessionState } from '@reticlehq/core';
2
+ import { pageHref } from '../security/page-location.js';
2
3
  import { LOG_KIND, LOG_RESULT } from './chrome/presenter-log.js';
3
4
  import { getCapabilities } from '../registry/capabilities.js';
4
5
  export function buildRunState(input) {
@@ -20,7 +21,7 @@ export function buildRunState(input) {
20
21
  }
21
22
  return {
22
23
  session: input.sessionId,
23
- url: 'undefined' === typeof location ? '' : location.href,
24
+ url: 'undefined' === typeof location ? '' : pageHref(),
24
25
  state: input.state,
25
26
  startedMs: start,
26
27
  durationMs: Math.max(0, (input.endMs ?? input.now) - start),
@@ -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,.62);font-size:13px;font-weight:500;}
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:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;}
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,.8);font-size:13px;
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:10px;line-height:1;flex:none;transition:background .12s,border-color .12s,color .12s;}
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,6 @@
1
1
  import type { HarnessConfig } from '@reticlehq/core';
2
2
  import { SETTINGS_CSS } from './presenter-settings-styles.js';
3
+ import { type Credits } from '@reticlehq/core/hud';
3
4
  import type { AccountState } from '@reticlehq/core';
4
5
  import { type AccountDetails } from './presenter-account.js';
5
6
  export { SETTINGS_CSS };
@@ -41,12 +42,11 @@ export interface PresenterSettings {
41
42
  export declare function getPresenterSettings(): PresenterSettings;
42
43
  export declare function loadPresenterSettings(): PresenterSettings;
43
44
  export declare const SETTINGS_ACCOUNT_ATTR = "data-reticle-settings-account";
44
- export declare function creditsLeft(credits: {
45
- used: number;
46
- limit: number;
47
- } | undefined): string;
45
+ export declare const HARNESS_LOCKED_HELP = "The Harness is not available to this workspace right now: see Plan in your Reticle dashboard.";
46
+ export declare function creditsLeft(credits: Credits | undefined): string;
48
47
  export declare function paintHarnessRow(root: ParentNode, config: HarnessConfig | undefined): void;
49
48
  export declare function paintSettingsAccount(root: HTMLElement, account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
49
+ export declare function paintSdkVersion(root: ParentNode, version: string | undefined): void;
50
50
  export declare function settingsPanelHtml(): string;
51
51
  export interface SettingsHost {
52
52
  onHideUntilRestart?: () => void;