@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
@@ -4,8 +4,9 @@ import { HUD_SURFACE_CLASS } from './chrome/presenter-hud-chrome.js';
4
4
  import { resetHudDockPosition } from './presenter-drag.js';
5
5
  import { findDock, scheduleSyncDockLayout } from './presenter-dock-layout.js';
6
6
  import { SETTINGS_CSS } from './presenter-settings-styles.js';
7
+ import { creditsLeftText, creditsSpent, creditsUsedText } from '@reticlehq/core/hud';
7
8
  import { DISCOVERY_CALL_URL, FOUNDER_EMAIL, FOUNDER_MAILTO } from '@reticlehq/core';
8
- import { ACCOUNT_TEXT, accountControlHtml, } from './presenter-account.js';
9
+ import { ACCOUNT_TEXT, accountControlHtml, paintAccountSlot, } from './presenter-account.js';
9
10
  export { SETTINGS_CSS };
10
11
  export const OutputDetail = {
11
12
  MINIMAL: 'minimal',
@@ -131,36 +132,56 @@ function patchSettings(patch) {
131
132
  function settingsHelpIcon() {
132
133
  return hiIconHtml(PresenterIcon.HELP, PRESENTER_ICON_SIZE.HELP);
133
134
  }
134
- function settingsLabel(text, helpTitle) {
135
+ const SETTING_TEXT = {
136
+ outputDetail: ['Output detail', 'How much a copied run includes.'],
137
+ autoOpenChat: [
138
+ 'Open the log automatically',
139
+ 'Opens this panel when an agent starts to act in this tab.',
140
+ ],
141
+ showTimestamps: ['Show timestamps', 'Shows how long ago each log row happened.'],
142
+ showTally: ['Show pass/fail count', 'A score pill for this session in the toolbar.'],
143
+ reactComponents: ['React component names', 'Adds component names to copied runs.'],
144
+ blockPageInteractions: [
145
+ 'Block page while adding notes',
146
+ 'Clicks pin a note instead of using the app.',
147
+ ],
148
+ clearOnCopy: ['Clear notes after copying', 'Starts fresh once your notes are copied.'],
149
+ hideUntilRestart: ['Hide until reload', 'Hides the HUD until this page reloads.'],
150
+ harnessEnabled: ['Allow Reticle to drive', 'Off by default. Lets Run Harness test this project.'],
151
+ reduceMotion: ['Reduce motion', 'Fewer HUD animations.'],
152
+ ambientGlow: ['Page glow', 'Tints the page edges while a session runs.'],
153
+ workspace: ['Workspace', 'The Reticle account this machine is signed in to.'],
154
+ };
155
+ function settingsLabel(text, helpTitle, desc = '') {
135
156
  const help = settingsHelpIcon();
136
- return `<span class="reticle-settings-label">${text}<button type="button" class="reticle-settings-help" data-reticle-settings-help title="${helpTitle}" aria-label="${helpTitle}">${help}</button></span>`;
157
+ const line = '' === desc ? '' : `<span class="reticle-settings-desc">${desc}</span>`;
158
+ return `<span class="reticle-settings-labelcol"><span class="reticle-settings-label">${text}<button type="button" class="reticle-settings-help" data-reticle-settings-help title="${helpTitle}" aria-label="${helpTitle}">${help}</button></span>${line}</span>`;
137
159
  }
138
- function settingsToggleRow(key, label, helpTitle, extra = '') {
160
+ function settingsToggleRow(key, helpTitle, extra = '') {
161
+ const [label, desc] = SETTING_TEXT[key];
139
162
  return `<div class="reticle-settings-row" ${extra}>
140
- ${settingsLabel(label, helpTitle)}
163
+ ${settingsLabel(label, helpTitle, desc)}
141
164
  <button type="button" class="reticle-settings-toggle" ${SETTING_KEY_ATTR}="${key}" role="switch" aria-checked="false"></button>
142
165
  </div>`;
143
166
  }
144
- function settingsCheckRow(key, label, checked) {
167
+ function settingsCheckRow(key, checked) {
168
+ const [label, desc] = SETTING_TEXT[key];
145
169
  const on = checked ? 'true' : 'false';
146
170
  return `<label class="reticle-settings-checkrow" data-reticle-check-row="${key}">
147
171
  <span class="reticle-settings-check" data-reticle-check="${key}" role="checkbox" aria-checked="${on}" tabindex="0"></span>
148
- <span class="reticle-settings-check-label">${label}</span>
172
+ <span class="reticle-settings-labelcol"><span class="reticle-settings-check-label">${label}</span><span class="reticle-settings-desc">${desc}</span></span>
149
173
  </label>`;
150
174
  }
151
175
  export const SETTINGS_ACCOUNT_ATTR = 'data-reticle-settings-account';
152
176
  const SETTINGS_ACCOUNT_ROW_ATTR = 'data-reticle-settings-account-row';
153
177
  const HELP_TEXT_ATTR = 'data-reticle-settings-helptext';
154
178
  const SETTINGS_HARNESS_ROW_ATTR = 'data-reticle-settings-harness-row';
155
- const HARNESS_HELP = 'Let Reticle drive this app by itself to find defects. Set here or in your dashboard — both write to the same place.';
156
- const HARNESS_LOCKED_HELP = 'The Harness is not available to this workspace right now. Every workspace gets free Harness credits each month: see Plan in your Reticle dashboard.';
179
+ const HARNESS_HELP = 'Let Reticle test this app by itself to find defects, from Run Harness or from your coding agent. Off blocks every run. Set here or in your dashboard — both write to the same place.';
180
+ export const HARNESS_LOCKED_HELP = 'The Harness is not available to this workspace right now: see Plan in your Reticle dashboard.';
157
181
  export function creditsLeft(credits) {
158
182
  if (credits === undefined)
159
183
  return '';
160
- const left = Math.max(0, credits.limit - credits.used);
161
- return 0 === left
162
- ? `All ${String(credits.limit)} Harness credits used this month`
163
- : `${String(left)} of ${String(credits.limit)} Harness credits left this month`;
184
+ return creditsSpent(credits) ? creditsUsedText(credits).said : creditsLeftText(credits);
164
185
  }
165
186
  const ACCOUNT_HELP = `Whether this machine is signed in to a Reticle workspace. Press ${ACCOUNT_TEXT.SIGNED_OUT} to sign in through your browser.`;
166
187
  export function paintHarnessRow(root, config) {
@@ -178,12 +199,14 @@ export function paintHarnessRow(root, config) {
178
199
  const usable = config.harnessEntitled;
179
200
  toggle.setAttribute('aria-checked', config.harnessEnabled && usable ? 'true' : 'false');
180
201
  toggle.setAttribute('aria-disabled', usable ? 'false' : 'true');
181
- const help = row.querySelector('[data-reticle-help]');
202
+ const help = row.querySelector('[data-reticle-settings-help]');
182
203
  const credits = creditsLeft(config.credits);
183
204
  if (help instanceof HTMLElement)
184
205
  help.title = usable
185
206
  ? [HARNESS_HELP, credits].filter((t) => 0 < t.length).join(' ')
186
- : HARNESS_LOCKED_HELP;
207
+ : creditsSpent(config.credits)
208
+ ? credits
209
+ : HARNESS_LOCKED_HELP;
187
210
  }
188
211
  export function paintSettingsAccount(root, account, dashboardUrl, details = {}) {
189
212
  const row = root.querySelector(`[${SETTINGS_ACCOUNT_ROW_ATTR}]`);
@@ -192,7 +215,7 @@ export function paintSettingsAccount(root, account, dashboardUrl, details = {})
192
215
  return;
193
216
  const html = accountControlHtml(account, { ...details, dashboardUrl }, true);
194
217
  row.hidden = 0 === html.length;
195
- slot.innerHTML = html;
218
+ paintAccountSlot(slot, html);
196
219
  }
197
220
  const FEEDBACK_TEXT = {
198
221
  EMAIL: 'Email the founder',
@@ -206,6 +229,17 @@ const KILL_TEXT = {
206
229
  ARMED: 'Click again to kill Reticle',
207
230
  WARNING: 'Disconnects Reticle from this page: no HUD, no agent, nothing recorded. To bring it back, restart your dev server or reload the page.',
208
231
  };
232
+ const SDK_VERSION_ATTR = 'data-reticle-sdk-version';
233
+ const SDK_VERSION_TEXT = {
234
+ UNKNOWN: 'Reticle SDK version unknown',
235
+ KNOWN: (version) => `Reticle SDK ${version}`,
236
+ };
237
+ export function paintSdkVersion(root, version) {
238
+ const line = root.querySelector(`[${SDK_VERSION_ATTR}]`);
239
+ if (line !== null)
240
+ line.textContent =
241
+ version === undefined ? SDK_VERSION_TEXT.UNKNOWN : SDK_VERSION_TEXT.KNOWN(version);
242
+ }
209
243
  export function settingsPanelHtml() {
210
244
  const close = hiIconHtml(PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.MIN);
211
245
  const caret = hiIconHtml(PresenterIcon.CARET_RIGHT, PRESENTER_ICON_SIZE.HELP);
@@ -227,27 +261,27 @@ export function settingsPanelHtml() {
227
261
  <div class="reticle-settings-body">
228
262
  <div class="reticle-settings-section">Session</div>
229
263
  <div class="reticle-settings-row">
230
- ${settingsLabel('Output Detail', outputHelp)}
264
+ ${settingsLabel(SETTING_TEXT.outputDetail[0], outputHelp, SETTING_TEXT.outputDetail[1])}
231
265
  <button type="button" class="reticle-settings-cycle" data-reticle-settings-cycle="outputDetail"><span data-reticle-cycle-label></span><span class="reticle-settings-dots" data-reticle-cycle-dots></span></button>
232
266
  </div>
233
- ${settingsToggleRow('autoOpenChat', 'Auto-open chat', autoChatHelp)}
234
- ${settingsToggleRow('showTimestamps', 'Show timestamps', timestampsHelp)}
235
- ${settingsToggleRow('showTally', 'Show verdict tally', tallyHelp)}
267
+ ${settingsToggleRow('autoOpenChat', autoChatHelp)}
268
+ ${settingsToggleRow('showTimestamps', timestampsHelp)}
269
+ ${settingsToggleRow('showTally', tallyHelp)}
236
270
  <div class="reticle-settings-section">Inspector</div>
237
- ${settingsToggleRow('reactComponents', 'React Components', reactHelp, 'data-reticle-settings-react-row')}
271
+ ${settingsToggleRow('reactComponents', reactHelp, 'data-reticle-settings-react-row')}
238
272
  <div class="reticle-settings-section">Interaction</div>
239
- ${settingsCheckRow('blockPageInteractions', 'Block page while adding notes', true)}
240
- ${settingsCheckRow('clearOnCopy', 'Clear notes after copying', false)}
241
- ${settingsToggleRow('hideUntilRestart', 'Hide until reload', hideHelp)}
242
- ${settingsToggleRow('harnessEnabled', 'Autonomous driving', harnessHelp, `${SETTINGS_HARNESS_ROW_ATTR} hidden`)}
243
- ${settingsToggleRow('reduceMotion', 'Reduce motion', motionHelp)}
273
+ ${settingsCheckRow('blockPageInteractions', true)}
274
+ ${settingsCheckRow('clearOnCopy', false)}
275
+ ${settingsToggleRow('hideUntilRestart', hideHelp)}
276
+ ${settingsToggleRow('harnessEnabled', harnessHelp, `${SETTINGS_HARNESS_ROW_ATTR} hidden`)}
277
+ ${settingsToggleRow('reduceMotion', motionHelp)}
244
278
  <div class="reticle-settings-section">Account</div>
245
279
  <div class="reticle-settings-row" ${SETTINGS_ACCOUNT_ROW_ATTR} hidden>
246
- ${settingsLabel('Workspace', ACCOUNT_HELP)}
280
+ ${settingsLabel(SETTING_TEXT.workspace[0], ACCOUNT_HELP, SETTING_TEXT.workspace[1])}
247
281
  <span ${SETTINGS_ACCOUNT_ATTR}></span>
248
282
  </div>
249
283
  <div class="reticle-settings-section">Status theme</div>
250
- ${settingsToggleRow('ambientGlow', 'Page glow', glowHelp)}
284
+ ${settingsToggleRow('ambientGlow', glowHelp)}
251
285
  <div class="reticle-settings-themes" data-reticle-settings-themes></div>
252
286
  <div class="reticle-settings-section">Help</div>
253
287
  <div class="reticle-settings-foot">
@@ -255,6 +289,7 @@ export function settingsPanelHtml() {
255
289
  <button type="button" class="reticle-settings-link" data-reticle-settings-mcp>MCP setup guide<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></button>
256
290
  <a class="reticle-settings-link" data-reticle-feedback-email href="${FOUNDER_MAILTO}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.EMAIL_TITLE}">${FEEDBACK_TEXT.EMAIL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
257
291
  <a class="reticle-settings-link" data-reticle-feedback-call href="${DISCOVERY_CALL_URL}" target="_blank" rel="noopener noreferrer" title="${FEEDBACK_TEXT.CALL_TITLE}">${FEEDBACK_TEXT.CALL}<span class="reticle-settings-link-caret" aria-hidden="true">${caret}</span></a>
292
+ <p class="reticle-settings-kill-sub" ${SDK_VERSION_ATTR}>${SDK_VERSION_TEXT.UNKNOWN}</p>
258
293
  <div class="reticle-settings-kill-row">
259
294
  <button type="button" class="reticle-settings-kill" ${KILL_ATTR}><span data-reticle-kill-label>${KILL_TEXT.LABEL}</span></button>
260
295
  <p class="reticle-settings-kill-sub">${KILL_TEXT.WARNING}</p>
@@ -317,7 +352,10 @@ export class PresenterSettingsPanel {
317
352
  setHiIcon(closeBtn, PresenterIcon.REMOVE, PRESENTER_ICON_SIZE.MIN);
318
353
  }
319
354
  if (this.#btn !== undefined) {
355
+ const label = this.#btn.querySelector('.reticle-nav-label');
320
356
  setHiIcon(this.#btn, PresenterIcon.GEAR, PRESENTER_ICON_SIZE.TOOLBAR);
357
+ if (null !== label)
358
+ this.#btn.append(label);
321
359
  this.#btn.addEventListener('click', (e) => {
322
360
  e.stopPropagation();
323
361
  this.open();
@@ -88,8 +88,7 @@ export const SHELL_CSS = `
88
88
  [${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] [data-reticle-log]{
89
89
  pointer-events:none;}
90
90
  /* ...except a log with more than it shows: a feed nobody can scroll back through is not a log. */
91
- [${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] [data-reticle-log][data-reticle-log-scrollable],
92
- [${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] .reticle-flow-strip{
91
+ [${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] [data-reticle-log][data-reticle-log-scrollable]{
93
92
  pointer-events:auto;}
94
93
  [${OVERLAY}][data-reticle-mode="idle"][data-reticle-block="0"] [${CHAT_PANEL}] :is(button,a,input,select,textarea){
95
94
  pointer-events:auto;}
@@ -132,6 +131,14 @@ export const SHELL_CSS = `
132
131
  so the two never overlap. The :empty rule keeps the gap closed when no account state was sent. */
133
132
  [${CHAT_PANEL}] .reticle-head-account{margin-left:auto;display:inline-flex;align-items:center;}
134
133
  [${CHAT_PANEL}] .reticle-head-account:empty{display:none;}
134
+ /* The quiet way to the platform: one line of small text before the avatar, cut short before it pushes. */
135
+ [${CHAT_PANEL}] .reticle-head-team{margin-left:auto;min-width:0;display:inline-flex;}
136
+ [${CHAT_PANEL}] .reticle-head-team:empty{display:none;}
137
+ [${CHAT_PANEL}] .reticle-head-team:not(:empty) + .reticle-head-account{margin-left:0;}
138
+ [${CHAT_PANEL}] .reticle-team-link{min-width:0;max-width:100%;overflow:hidden;padding:0;border:0;background:none;cursor:pointer;font:inherit;font-size:var(--reticle-hud-size-xs);font-weight:500;color:var(--reticle-hud-text-muted);text-decoration:none;white-space:nowrap;text-overflow:ellipsis;}
139
+ [${CHAT_PANEL}] .reticle-team-link span{display:block;overflow:hidden;text-overflow:ellipsis;}
140
+ [${CHAT_PANEL}] .reticle-team-link:hover{color:var(--reticle-hud-brand);}
141
+ [${CHAT_PANEL}] .reticle-team-link:focus-visible{outline:2px solid var(--reticle-hud-brand);outline-offset:2px;border-radius:var(--reticle-hud-radius-sm);}
135
142
  [${CHAT_PANEL}] .reticle-chat-brand .reticle-mark{height:14px;width:auto;}
136
143
  [${CHAT_PANEL}] .reticle-chat-brandname{font-size:12.5px;font-weight:600;letter-spacing:.01em;}
137
144
  [${CHAT_PANEL}] .reticle-view-heading{display:flex;justify-content:space-between;align-items:baseline;gap:8px;min-height:28px;box-sizing:border-box;padding:6px 12px 4px;border-bottom:1px solid var(--reticle-hud-border);}
@@ -255,7 +262,7 @@ export const SHELL_CSS = `
255
262
  [${HUD}] .reticle-toolbar-actions{
256
263
  display:inline-flex;align-items:center;gap:2px;flex:none;
257
264
  padding:2px;border-radius:999px;background:rgba(0,0,0,.2);}
258
- [${HUD}] .reticle-toolbar-chrome{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));align-items:center;gap:var(--reticle-hud-space-1);flex:1;min-width:0;}
265
+ [${HUD}] .reticle-toolbar-chrome{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);align-items:center;gap:var(--reticle-hud-space-1);flex:1;min-width:0;}
259
266
  [${HUD}] .reticle-tb-sep{width:1px;height:14px;background:rgba(255,255,255,.12);margin:0 4px;flex:none;align-self:center;}
260
267
 
261
268
  [${HUD}] .reticle-tb-wrap{position:relative;display:flex;align-items:center;justify-content:center;overflow:visible;}
@@ -370,6 +377,8 @@ export const SHELL_CSS = `
370
377
  */
371
378
  [${OVERLAY}][${STATE}="unreachable"]{--reticle-state:var(--reticle-faint);}
372
379
  [${OVERLAY}][${STATE}="unreachable"] [${CHAT_PANEL}] .reticle-act-dot{animation:none;}
380
+ /* The one status that is a sentence to act on: two lines, full contrast, the detail on hover. */
381
+ [${OVERLAY}][${STATE}="unreachable"] [${CHAT_PANEL}] .reticle-act{white-space:normal;line-height:1.35;color:var(--reticle-fg);cursor:help;}
373
382
  [${OVERLAY}][${STATE}="paused"] [${CHAT_PANEL}] .reticle-act-dot,
374
383
  [${OVERLAY}][${STATE}="ended"] [${CHAT_PANEL}] .reticle-act-dot{animation:none;}
375
384
  @keyframes reticle-idle-pulse{0%,100%{opacity:.45;transform:scale(.92)}50%{opacity:1;transform:scale(1)}}
@@ -1,8 +1,7 @@
1
- import type { HarnessConfig } from '@reticlehq/core';
1
+ import type { AgentLink, HarnessConfig, HarnessDrive, LastDrive } from '@reticlehq/core';
2
2
  import { PresenterReport } from './presenter-report.js';
3
3
  import type { AccountState } from '@reticlehq/core';
4
4
  import { type AccountDetails } from './presenter-account.js';
5
- import { type OfferState } from './carousel/offer-card.js';
6
5
  import { type ChatView } from './presenter-chat-views.js';
7
6
  import type { AnnotationItem } from '../review/annotator.js';
8
7
  import { type SettingsHost } from './presenter-settings.js';
@@ -14,17 +13,23 @@ interface HudShellCallbacks {
14
13
  onCollapse?: () => void;
15
14
  onSyncNow?: () => void;
16
15
  onHarness?: (enabled: boolean) => void;
16
+ onHarnessRun?: (persona?: string) => void;
17
+ onHarnessStop?: () => void;
18
+ onHarnessLink?: () => void;
17
19
  onSignIn?: () => void;
18
20
  settings?: SettingsHost;
19
21
  }
20
22
  export declare class HudShell {
21
23
  #private;
24
+ setProjectId(projectId: string | undefined): void;
25
+ paintHarnessDrive(drive: HarnessDrive | undefined, last?: LastDrive): void;
26
+ paintAgent(link: AgentLink | undefined): void;
22
27
  paintHarness(config: HarnessConfig | undefined): void;
23
28
  paintImpact(verdicts: number): void;
24
29
  paintAnnotations(items: readonly AnnotationItem[]): void;
25
30
  openView(view: ChatView): void;
26
31
  paintAccount(account: AccountState | undefined, dashboardUrl: string | undefined, details?: AccountDetails): void;
27
- paintOffer(offer: OfferState | undefined, notices?: readonly unknown[]): void;
32
+ paintNotices(notices?: readonly unknown[]): void;
28
33
  constructor(callbacks?: HudShellCallbacks);
29
34
  static dockHtml(actStripHtml: string, bannerHtml: string, logAttr: string, flowsHtml: string, footHtml: string): string;
30
35
  get report(): PresenterReport;
@@ -44,5 +49,8 @@ export declare class HudShell {
44
49
  }
45
50
  export declare function wasMinimised(): boolean;
46
51
  export declare function rememberMinimised(minimised: boolean): void;
52
+ export declare function wasLeftOpen(): boolean;
53
+ export declare function rememberLeftOpen(open: boolean): void;
54
+ export declare function shouldReopenPanel(): boolean;
47
55
  export declare function shouldAutoOpenChat(autoOpenChat: boolean): boolean;
48
56
  export {};
@@ -1,20 +1,19 @@
1
1
  import { appModalOpen } from '../dom/dom-ignore.js';
2
2
  import { PresenterReport, reportPanelHtml } from './presenter-report.js';
3
3
  import { paintToolbarAccount, TOOLBAR_ACCOUNT_ATTR } from './presenter-workspace.js';
4
- import { mountAccountControl } from './presenter-account.js';
4
+ import { mountAccountControl, TEAM_SLOT_ATTR } from './presenter-account.js';
5
5
  import { paintSettingsAccount } from './presenter-settings.js';
6
- import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, MINIMISED_STORAGE_KEY, } from './presenter-config.js';
7
- import { offerDismissed } from './carousel/offer-card.js';
6
+ import { CHAT_MIN_ATTR, CHAT_PILL_ATTR, REPORT_ATTR, ANNOTATE_BTN_ATTR, CHAT_ATTR, CHAT_TOGGLE_ATTR, CHAT_PANEL_ATTR, DOCK_ATTR, FAB_ATTR, MIN_ATTR, SETTINGS_ATTR, SETTINGS_BTN_ATTR, MINIMISED_STORAGE_KEY, OPEN_STORAGE_KEY, } from './presenter-config.js';
8
7
  import { paintCarousel } from './carousel/carousel.js';
9
8
  import { panelSlides } from './carousel/panel-slides.js';
10
- import { paintRail, RAIL_HTML, RAIL_PROMO_ATTR } from './presenter-frame.js';
9
+ import { paintRail, RAIL_HTML, RAIL_PROMO_ATTR, RAIL_SIGNIN_HTML } from './presenter-frame.js';
11
10
  import { FAB_TOGGLE_HTML, MARK_SVG } from './chrome/presenter-brand.js';
12
11
  import { settleLogAtLatest } from './chrome/presenter-log.js';
13
12
  import { installHudDragHandles, installHudPositionGuards } from './presenter-drag.js';
14
13
  import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
15
14
  import { hiIconHtml, hiToggleIconHtml, PRESENTER_ICON_SIZE, PresenterIcon, } from './icons/presenter-icons.js';
16
15
  import { HUD_SURFACE_CLASS, HUD_LOG_WELL_CLASS } from './chrome/presenter-hud-chrome.js';
17
- import { ChatViews, CHAT_VIEWS_NAV_HTML, ANNOTATIONS_HTML, FLOWS_PAGE_HTML, platformBase, } from './presenter-chat-views.js';
16
+ import { ChatViews, CHAT_VIEWS_NAV_HTML, ANNOTATIONS_HTML, FLOWS_PAGE_HTML, HARNESS_PAGE_HTML, NAV_LABEL, navLabelHtml, platformBase, } from './presenter-chat-views.js';
18
17
  import { PresenterSettingsPanel, settingsPanelHtml, } from './presenter-settings.js';
19
18
  const DRAG_HANDLE_CLASS = 'reticle-toolbar-drag';
20
19
  const TRANSITION_LOCK_MS = 120;
@@ -23,16 +22,10 @@ const CHAT_PILL_LABEL = 'Open agent chat';
23
22
  const SETTINGS_LABEL = 'Settings';
24
23
  const AGENT_LOG_TITLE = 'Reticle';
25
24
  const EXIT_LABEL = 'Exit';
26
- function paintPromo(root, offer, notices = [], base) {
25
+ function paintPromo(root, notices = [], base) {
27
26
  const target = root.querySelector(`[${RAIL_PROMO_ATTR}]`);
28
27
  if (null === target)
29
28
  return;
30
- let dismissed = false;
31
- try {
32
- dismissed = offerDismissed(window.localStorage);
33
- }
34
- catch {
35
- }
36
29
  let storage;
37
30
  try {
38
31
  storage = window.sessionStorage;
@@ -40,7 +33,7 @@ function paintPromo(root, offer, notices = [], base) {
40
33
  catch {
41
34
  storage = undefined;
42
35
  }
43
- paintCarousel(target, panelSlides(offer, dismissed, notices, base), storage);
36
+ paintCarousel(target, panelSlides(notices, base), storage);
44
37
  }
45
38
  export class HudShell {
46
39
  #root;
@@ -67,11 +60,19 @@ export class HudShell {
67
60
  });
68
61
  #callbacks;
69
62
  #pushedAccount;
70
- #pushedOffer;
71
63
  #pushedNotices = [];
72
64
  #pushedHarness;
73
65
  #promoBase;
74
66
  #accountTeardown;
67
+ setProjectId(projectId) {
68
+ this.#chatViews.setProjectId(projectId);
69
+ }
70
+ paintHarnessDrive(drive, last) {
71
+ this.#chatViews.paintDrive(drive, last);
72
+ }
73
+ paintAgent(link) {
74
+ this.#chatViews.paintAgent(link);
75
+ }
75
76
  paintHarness(config) {
76
77
  this.#pushedHarness = config;
77
78
  this.#settings.paintHarness(config);
@@ -86,7 +87,7 @@ export class HudShell {
86
87
  if (this.#root === undefined || base === this.#promoBase)
87
88
  return;
88
89
  this.#promoBase = base;
89
- paintPromo(this.#root, this.#pushedOffer, this.#pushedNotices, base);
90
+ paintPromo(this.#root, this.#pushedNotices, base);
90
91
  }
91
92
  paintImpact(verdicts) {
92
93
  this.#chatViews.paintImpact(verdicts);
@@ -116,16 +117,15 @@ export class HudShell {
116
117
  this.#chatViews.paintAccount(account);
117
118
  this.#repaintPromoIfMoved();
118
119
  }
119
- paintOffer(offer, notices = []) {
120
- this.#pushedOffer = offer;
120
+ paintNotices(notices = []) {
121
121
  this.#pushedNotices = notices;
122
122
  this.#promoBase = this.#promoLinks();
123
123
  if (this.#root !== undefined)
124
- paintPromo(this.#root, offer, notices, this.#promoBase);
124
+ paintPromo(this.#root, notices, this.#promoBase);
125
125
  }
126
126
  constructor(callbacks = {}) {
127
127
  this.#callbacks = callbacks;
128
- this.#chatViews = new ChatViews((enabled) => callbacks.onHarness?.(enabled), () => {
128
+ this.#chatViews = new ChatViews(() => {
129
129
  this.#chatViews.closePage();
130
130
  this.closeChat();
131
131
  this.#report.open();
@@ -140,6 +140,11 @@ export class HudShell {
140
140
  this.closeChat();
141
141
  this.#settings.close();
142
142
  this.#report.close();
143
+ }, {
144
+ run: (persona) => callbacks.onHarnessRun?.(persona),
145
+ stop: () => callbacks.onHarnessStop?.(),
146
+ setHarness: (on) => callbacks.onHarness?.(on),
147
+ link: () => callbacks.onHarnessLink?.(),
143
148
  });
144
149
  this.#settings = new PresenterSettingsPanel({
145
150
  ...callbacks.settings,
@@ -158,6 +163,7 @@ export class HudShell {
158
163
  <div ${CHAT_PANEL_ATTR} class="reticle-chat-panel ${HUD_SURFACE_CLASS}" role="region" aria-label="Agent Log" aria-hidden="true">
159
164
  <div class="reticle-chat-head">
160
165
  <span class="reticle-chat-brand">${MARK_SVG}<span class="reticle-chat-brandname">${AGENT_LOG_TITLE}</span></span>
166
+ <span ${TEAM_SLOT_ATTR} class="reticle-head-team"></span>
161
167
  <span ${TOOLBAR_ACCOUNT_ATTR} class="reticle-head-account"></span>
162
168
  </div>
163
169
  <button type="button" ${CHAT_MIN_ATTR} class="reticle-chat-min" title="${CHAT_MIN_LABEL}" aria-label="${CHAT_MIN_LABEL}">${hiIconHtml(PresenterIcon.CARET_DOWN, PRESENTER_ICON_SIZE.TOOLBAR)}</button>
@@ -168,9 +174,11 @@ export class HudShell {
168
174
  <div class="${HUD_LOG_WELL_CLASS}"><div ${logAttr}></div></div>
169
175
  ${flowsHtml}
170
176
  </section>
177
+ ${RAIL_SIGNIN_HTML}
171
178
  ${footHtml}
172
179
  </div>
173
180
  ${FLOWS_PAGE_HTML}
181
+ ${HARNESS_PAGE_HTML}
174
182
  ${ANNOTATIONS_HTML}
175
183
  <button type="button" ${CHAT_PILL_ATTR} class="reticle-chat-pill" title="${CHAT_PILL_LABEL}" aria-label="${CHAT_PILL_LABEL}">
176
184
  ${MARK_SVG}
@@ -188,11 +196,11 @@ export class HudShell {
188
196
  <div class="reticle-toolbar-chrome">
189
197
  ${CHAT_VIEWS_NAV_HTML}
190
198
  <div class="reticle-tb-wrap">
191
- <button type="button" ${SETTINGS_BTN_ATTR} class="reticle-tb-btn reticle-tb-btn--toggle" title="${SETTINGS_LABEL}" aria-label="${SETTINGS_LABEL}" aria-pressed="false" data-active="0">${gear}</button>
199
+ <button type="button" ${SETTINGS_BTN_ATTR} class="reticle-tb-btn reticle-tb-btn--toggle" title="${SETTINGS_LABEL}" aria-label="${SETTINGS_LABEL}" aria-pressed="false" data-active="0">${gear}${navLabelHtml(NAV_LABEL.SETTINGS)}</button>
192
200
  <span class="reticle-tb-tip">${SETTINGS_LABEL}</span>
193
201
  </div>
194
202
  <div class="reticle-tb-wrap">
195
- <button type="button" data-reticle-min-btn class="reticle-tb-btn" title="${EXIT_LABEL}" aria-label="${EXIT_LABEL}">${exit}</button>
203
+ <button type="button" data-reticle-min-btn class="reticle-tb-btn" title="${EXIT_LABEL}" aria-label="${EXIT_LABEL}">${exit}${navLabelHtml(NAV_LABEL.HIDE)}</button>
196
204
  <span class="reticle-tb-tip">${EXIT_LABEL}<span class="reticle-tb-kbd">Esc</span></span>
197
205
  </div>
198
206
  </div>
@@ -218,6 +226,7 @@ export class HudShell {
218
226
  if (impact !== null) {
219
227
  const on = '1' === root.getAttribute(REPORT_ATTR);
220
228
  impact.setAttribute('data-active', on ? '1' : '0');
229
+ this.#chatViews.setImpactOpen(on);
221
230
  if (on)
222
231
  impact.setAttribute('aria-current', 'page');
223
232
  else
@@ -262,12 +271,14 @@ export class HudShell {
262
271
  pillEl?.addEventListener('click', (e) => {
263
272
  e.preventDefault();
264
273
  e.stopPropagation();
274
+ rememberLeftOpen(true);
265
275
  this.showChat();
266
276
  }, { signal });
267
277
  const chatMinEl = root.querySelector(`[${CHAT_MIN_ATTR}]`);
268
278
  chatMinEl?.addEventListener('click', (e) => {
269
279
  e.preventDefault();
270
280
  e.stopPropagation();
281
+ rememberLeftOpen(false);
271
282
  this.closeChat();
272
283
  }, { signal });
273
284
  const collapseEl = root.querySelector('[data-reticle-min-btn]');
@@ -279,7 +290,7 @@ export class HudShell {
279
290
  this.#report.mount(root);
280
291
  this.#chatViews.mount(root);
281
292
  this.#promoBase = this.#promoLinks();
282
- paintPromo(root, this.#pushedOffer, this.#pushedNotices, this.#promoBase);
293
+ paintPromo(root, this.#pushedNotices, this.#promoBase);
283
294
  this.#toggleSync = new MutationObserver(() => this.#syncToolbarToggles());
284
295
  this.#toggleSync.observe(root, {
285
296
  attributes: true,
@@ -292,10 +303,12 @@ export class HudShell {
292
303
  this.#suppressFabClick = false;
293
304
  return;
294
305
  }
306
+ rememberLeftOpen(true);
295
307
  this.expand();
296
308
  }, { signal });
297
309
  this.#collapseBtn?.addEventListener('click', (e) => {
298
310
  e.stopPropagation();
311
+ rememberLeftOpen(false);
299
312
  this.collapse();
300
313
  }, { signal });
301
314
  const toolbarDrag = root.querySelector(`.${DRAG_HANDLE_CLASS}`);
@@ -447,6 +460,7 @@ export class HudShell {
447
460
  return;
448
461
  }
449
462
  if (this.isChatOpen()) {
463
+ rememberLeftOpen(false);
450
464
  this.closeChat();
451
465
  return;
452
466
  }
@@ -455,6 +469,7 @@ export class HudShell {
455
469
  return;
456
470
  }
457
471
  if (!this.isCollapsed()) {
472
+ rememberLeftOpen(false);
458
473
  this.collapse();
459
474
  }
460
475
  };
@@ -477,6 +492,29 @@ export function rememberMinimised(minimised) {
477
492
  catch {
478
493
  }
479
494
  }
495
+ export function wasLeftOpen() {
496
+ try {
497
+ return '1' === globalThis.localStorage.getItem(OPEN_STORAGE_KEY);
498
+ }
499
+ catch {
500
+ return false;
501
+ }
502
+ }
503
+ export function rememberLeftOpen(open) {
504
+ try {
505
+ if (open) {
506
+ globalThis.localStorage.setItem(OPEN_STORAGE_KEY, '1');
507
+ }
508
+ else {
509
+ globalThis.localStorage.removeItem(OPEN_STORAGE_KEY);
510
+ }
511
+ }
512
+ catch {
513
+ }
514
+ }
515
+ export function shouldReopenPanel() {
516
+ return wasLeftOpen() && !wasMinimised();
517
+ }
480
518
  export function shouldAutoOpenChat(autoOpenChat) {
481
519
  return autoOpenChat && !wasMinimised();
482
520
  }
@@ -6,7 +6,6 @@ import { SETTINGS_CSS } from './presenter-settings-styles.js';
6
6
  import { ACCOUNT_CSS } from './presenter-account-styles.js';
7
7
  import { HUD_CHROME_CSS, HUD_LOG_WELL_CSS } from './chrome/presenter-hud-chrome.js';
8
8
  import { REPORT_CSS } from './presenter-report-styles.js';
9
- import { OFFER_CSS } from './carousel/offer-card.js';
10
9
  import { TALK_CSS } from './carousel/talk-card.js';
11
10
  import { CAROUSEL_CSS } from './carousel/carousel.js';
12
11
  import { CHAT_VIEWS_CSS } from './presenter-chat-views.js';
@@ -71,7 +70,6 @@ ${SHELL_CSS}
71
70
  ${SETTINGS_CSS}
72
71
  ${REPORT_CSS}
73
72
  ${ACCOUNT_CSS}
74
- ${OFFER_CSS}
75
73
  ${TALK_CSS}
76
74
  ${CAROUSEL_CSS}
77
75
  ${LOG_CSS}
@@ -1,6 +1,6 @@
1
1
  import { RETICLE_ROOT_GLOBAL, RETICLE_URL_PARAM } from '@reticlehq/core';
2
2
  import { PresenterIcon, PRESENTER_ICON_SIZE, hiIconHtml } from './icons/presenter-icons.js';
3
- import { ACCOUNT_SIGNIN_ATTR, ACCOUNT_TEXT, accountControlHtml, } from './presenter-account.js';
3
+ import { ACCOUNT_SIGNIN_ATTR, ACCOUNT_TEXT, accountControlHtml, paintAccountSlot, teamLinkHtml, TEAM_SLOT_ATTR, } from './presenter-account.js';
4
4
  const WORKSPACE_BTN_ATTR = 'data-reticle-workspace-btn';
5
5
  const WORKSPACE_MENU_ATTR = 'data-reticle-workspace-menu';
6
6
  const WORKSPACE_NAME_ATTR = 'data-reticle-workspace-name';
@@ -10,6 +10,8 @@ const WORKSPACE_COPY_ATTR = 'data-reticle-workspace-copy';
10
10
  export const TOOLBAR_ACCOUNT_ATTR = 'data-reticle-toolbar-account';
11
11
  const COPIED_MS = 1_200;
12
12
  const WORKSPACE_LABEL = 'Workspace';
13
+ const CHIP_KEY = 'Project';
14
+ const CHIP_TITLE = 'The project folder this page is served from, which Reticle reports to. Click for its path.';
13
15
  const PROJECT_LABEL = 'Project';
14
16
  const COPY_PATH_LABEL = 'Copy path';
15
17
  const COPIED_PATH_LABEL = 'Copied';
@@ -48,8 +50,9 @@ export function workspaceRowHtml() {
48
50
  const caret = hiIconHtml(PresenterIcon.CARET_DOWN, PRESENTER_ICON_SIZE.HELP);
49
51
  const copyIcon = hiIconHtml(PresenterIcon.COPY, PRESENTER_ICON_SIZE.HELP);
50
52
  return `<div class="reticle-workspace-wrap">
51
- <button type="button" class="reticle-workspace" ${WORKSPACE_BTN_ATTR} aria-haspopup="true" aria-expanded="false" title="${WORKSPACE_LABEL}">
53
+ <button type="button" class="reticle-workspace" ${WORKSPACE_BTN_ATTR} aria-haspopup="true" aria-expanded="false" title="${CHIP_TITLE}">
52
54
  <span class="reticle-workspace-icon" aria-hidden="true">${folderIcon}</span>
55
+ <span class="reticle-workspace-k">${CHIP_KEY}</span>
53
56
  <span class="reticle-workspace-name" ${WORKSPACE_NAME_ATTR}>${WORKSPACE_FALLBACK}</span>
54
57
  <span class="reticle-workspace-caret" aria-hidden="true">${caret}</span>
55
58
  </button>
@@ -193,8 +196,12 @@ export function mountWorkspaceSelector(root) {
193
196
  };
194
197
  }
195
198
  export function paintToolbarAccount(root, account, dashboardUrl, details = {}) {
199
+ const team = root.querySelector(`[${TEAM_SLOT_ATTR}]`);
200
+ if (team instanceof HTMLElement)
201
+ paintAccountSlot(team, teamLinkHtml(account, dashboardUrl));
196
202
  const slot = root.querySelector(`[${TOOLBAR_ACCOUNT_ATTR}]`);
197
203
  if (!(slot instanceof HTMLElement))
198
204
  return;
199
- slot.innerHTML = accountControlHtml(account, { ...details, dashboardUrl }, true);
205
+ const door = !(team instanceof HTMLElement);
206
+ paintAccountSlot(slot, accountControlHtml(account, { ...details, dashboardUrl }, door));
200
207
  }
@@ -17,6 +17,7 @@ export declare class Presenter {
17
17
  get sessionActive(): boolean;
18
18
  setState(state: SessionState, text?: string, tone?: PresenterTone): void;
19
19
  refilterFlows(): void;
20
+ showSdkVersion(version: string | undefined): void;
20
21
  handlePush(command: {
21
22
  name: string;
22
23
  args: Record<string, unknown>;
@@ -38,8 +39,8 @@ export declare class Presenter {
38
39
  placeHud(visibility: HudVisibility | undefined, corner: HudCorner | undefined): string[];
39
40
  setIdleEndMs(ms: number): void;
40
41
  runState(): PresenterRunState | Record<string, unknown>;
41
- log(kind: LogKind, text: string, result?: LogResult, actor?: LogActor): LogHandle | undefined;
42
- narrate(text: string, level?: string): LogHandle | undefined;
42
+ log(kind: LogKind, text: string, result?: LogResult, actor?: LogActor, summary?: boolean): LogHandle | undefined;
43
+ narrate(text: string, level?: string, actor?: LogActor, summary?: boolean): LogHandle | undefined;
43
44
  setThrottled(throttled: boolean): void;
44
45
  beforeAct(refId: string, action: string, label: string): Promise<void>;
45
46
  }