@reticlehq/browser 3.5.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 +56 -43
- package/dist/actions/actions-press.d.ts +11 -4
- package/dist/actions/actions-press.js +132 -17
- package/dist/actions/actions.d.ts +1 -35
- package/dist/actions/actions.js +32 -65
- package/dist/actions/appeared-text.js +3 -0
- package/dist/actions/danger-context.d.ts +2 -0
- package/dist/actions/danger-context.js +29 -3
- 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/connect-options.d.ts +1 -0
- package/dist/dom/a11y.js +264 -14
- package/dist/dom/addressing/coverage-markers.d.ts +6 -0
- package/dist/dom/addressing/coverage-markers.js +13 -0
- package/dist/dom/addressing/refs.js +2 -1
- package/dist/dom/addressing/testid-attr.d.ts +4 -0
- package/dist/dom/addressing/testid-attr.js +14 -0
- package/dist/dom/dom-ignore.d.ts +2 -0
- package/dist/dom/dom-ignore.js +15 -2
- package/dist/dom/query.d.ts +2 -1
- package/dist/dom/query.js +116 -27
- package/dist/dom/render-page.d.ts +12 -0
- package/dist/dom/render-page.js +135 -0
- package/dist/dom/snapshot.js +56 -7
- package/dist/observers/departure.js +51 -9
- package/dist/observers/dom.js +35 -18
- package/dist/observers/field.js +5 -21
- package/dist/observers/health.js +63 -2
- package/dist/observers/network-stream.d.ts +1 -1
- package/dist/observers/network-stream.js +3 -3
- package/dist/observers/network.js +57 -8
- package/dist/observers/perf.js +53 -1
- package/dist/observers/route.js +6 -5
- package/dist/observers/storage.js +6 -1
- package/dist/presenter/carousel/carousel.d.ts +5 -2
- package/dist/presenter/carousel/carousel.js +30 -8
- package/dist/presenter/carousel/panel-slides.d.ts +3 -4
- package/dist/presenter/carousel/panel-slides.js +48 -9
- package/dist/presenter/carousel/talk-card.d.ts +1 -1
- package/dist/presenter/chrome/log-kinds.d.ts +5 -0
- package/dist/presenter/chrome/log-kinds.js +1 -0
- package/dist/presenter/chrome/log-memory.d.ts +13 -0
- package/dist/presenter/chrome/log-memory.js +39 -0
- package/dist/presenter/chrome/presenter-hud-chrome.d.ts +1 -0
- package/dist/presenter/chrome/presenter-hud-chrome.js +7 -1
- package/dist/presenter/chrome/presenter-log.d.ts +12 -4
- package/dist/presenter/chrome/presenter-log.js +100 -10
- 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 +28 -5
- package/dist/presenter/chrome/presenter-report-copy.js +40 -5
- package/dist/presenter/hud-telemetry.js +83 -3
- package/dist/presenter/icons/presenter-heroicons-data.d.ts +1 -0
- package/dist/presenter/icons/presenter-heroicons-data.js +4 -3
- package/dist/presenter/icons/presenter-icons.d.ts +2 -0
- package/dist/presenter/icons/presenter-icons.js +2 -0
- package/dist/presenter/presenter-account-styles.js +3 -3
- package/dist/presenter/presenter-account.d.ts +31 -8
- package/dist/presenter/presenter-account.js +105 -15
- 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 +43 -0
- package/dist/presenter/presenter-chat-views.js +622 -0
- package/dist/presenter/presenter-config.d.ts +5 -2
- package/dist/presenter/presenter-config.js +5 -3
- package/dist/presenter/presenter-controls.d.ts +3 -2
- package/dist/presenter/presenter-controls.js +163 -61
- package/dist/presenter/presenter-design-tokens.d.ts +1 -0
- package/dist/presenter/presenter-design-tokens.js +34 -0
- package/dist/presenter/presenter-dock-layout.js +1 -1
- package/dist/presenter/presenter-frame.d.ts +12 -0
- package/dist/presenter/presenter-frame.js +187 -0
- 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.d.ts +10 -0
- package/dist/presenter/presenter-plan.js +186 -0
- package/dist/presenter/presenter-report-styles.js +46 -21
- package/dist/presenter/presenter-report.d.ts +2 -1
- package/dist/presenter/presenter-report.js +123 -20
- package/dist/presenter/presenter-settings-styles.js +18 -4
- package/dist/presenter/presenter-settings.d.ts +8 -2
- package/dist/presenter/presenter-settings.js +134 -33
- package/dist/presenter/presenter-shell-styles.js +48 -42
- package/dist/presenter/presenter-shell.d.ts +17 -4
- package/dist/presenter/presenter-shell.js +139 -79
- package/dist/presenter/presenter-styles.js +9 -3
- package/dist/presenter/presenter-workspace.js +10 -3
- package/dist/presenter/presenter.d.ts +6 -4
- package/dist/presenter/presenter.js +171 -22
- package/dist/presenter/tour/tour.d.ts +4 -1
- package/dist/presenter/tour/tour.js +6 -4
- package/dist/recorder/recorder.js +2 -2
- package/dist/registry/auto-testids.js +3 -4
- package/dist/registry/declared-platform.js +4 -0
- package/dist/reticle-inject.js +938 -494
- package/dist/reticle.d.ts +10 -1
- package/dist/reticle.js +109 -11
- package/dist/review/annotator-styles.d.ts +1 -1
- package/dist/review/annotator.d.ts +7 -0
- package/dist/review/annotator.js +20 -2
- package/dist/review/mark-anchor.js +2 -2
- package/dist/session-continuity.js +2 -1
- package/dist/storage-keys.d.ts +15 -0
- package/dist/storage-keys.js +21 -0
- 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 +3 -2
- package/dist/presenter/carousel/offer-card.d.ts +0 -21
- package/dist/presenter/carousel/offer-card.js +0 -55
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
import { ActionType, HumanControlKind, ReticleCommand, PresenterMode, SessionState, isPresenterTone, isSessionState, } from '@reticlehq/core';
|
|
1
|
+
import { ActionType, HudCorner, HudVisibility, HumanControlKind, ReticleCommand, PresenterMode, SessionState, isPresenterTone, isSessionState, } from '@reticlehq/core';
|
|
2
2
|
import { refs } from '../dom/addressing/refs.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UNREACHABLE_HEADLINE, unreachableMessage } from '../transport/unreachable-message.js';
|
|
4
4
|
import { actionVerb } from './chrome/presenter-verbs.js';
|
|
5
5
|
import { nativeSetTimeout, nativeClearTimeout, nativeNow } from '../timers/native/native-timers.js';
|
|
6
|
-
import { LOG_KIND, CHIP_LABEL, DATA_RETICLE_LOG, clampLogMax, formatElapsed, humanDuration, appendLogRow, clearLogRows, trimLogRows, } from './chrome/presenter-log.js';
|
|
6
|
+
import { LOG_KIND, CHIP_LABEL, LOG_ACTOR, DATA_RETICLE_LOG, clampLogMax, formatElapsed, humanDuration, appendLogRow, clearLogRows, trimLogRows, } from './chrome/presenter-log.js';
|
|
7
7
|
import { PRESENTER_CSS } from './presenter-styles.js';
|
|
8
8
|
import { HudShell } from './presenter-shell.js';
|
|
9
|
+
import { HARNESS_LOG_ATTR, harnessGateIn } from './presenter-harness-row.js';
|
|
10
|
+
import { platformDetails } from './presenter-account.js';
|
|
9
11
|
import { parseImpactSnapshot } from './chrome/presenter-report-copy.js';
|
|
10
|
-
import {
|
|
12
|
+
import { scheduleSyncDockLayout } from './presenter-dock-layout.js';
|
|
13
|
+
import { applyHudPosition, clampHudPosition, hudLayoutBox, resetHudDockPosition, } from './presenter-hud-position.js';
|
|
14
|
+
import { BorderMode, DEFAULT_BORDER_MODE, DOCK_ATTR, HIDDEN_UNTIL_RESTART_ATTR, DATA_BUSY, BUSY_OFF, effectivePaceMs, IDLE_AFTER_MS, HEARTBEAT_MS, IDLE_NOTICE_MS, IDLE_END_MS, IDLE_END_MIN_MS, ACT_STRIP, STATE_ATTR, UNREACHABLE_STATE, GLOW_FADE_MS, GLOW_ON, GLOW_OFF, DATA_ON, THROTTLED_ATTR, LIVENESS_ATTR, MARKERS_BTN_ATTR, CLEAR_MARKS_ATTR, COPY_MARKS_ATTR, MARKS_ROW_ATTR, MARK_COUNT_ATTR, } from './presenter-config.js';
|
|
11
15
|
import { buildRunState } from './presenter-run-state.js';
|
|
12
16
|
import { moveCursor, ringAround, spawnRipple, pace } from './chrome/presenter-effects.js';
|
|
13
17
|
import { GlowController } from './presenter-glow.js';
|
|
14
18
|
import { PresenterIcon, PRESENTER_ICON_SIZE, hiIcon } from './icons/presenter-icons.js';
|
|
15
19
|
import { renderTally } from './chrome/presenter-tally.js';
|
|
16
|
-
import { CONTROLS_BANNER_HTML,
|
|
17
|
-
import { statusTheme, blockerHtml, getPresenterSettings, OutputDetail, syncPageBlocker, } from './presenter-settings.js';
|
|
20
|
+
import { CONTROLS_BANNER_HTML, CONTROLS_MARKS_HTML, CONTROLS_FOOT_HTML, CONTROLS_STATUS_HTML, ENDED_FADE_MS, ControlPanel, } from './presenter-controls.js';
|
|
21
|
+
import { statusTheme, blockerHtml, getPresenterSettings, OutputDetail, syncPageBlocker, paintSdkVersion, } from './presenter-settings.js';
|
|
18
22
|
import { Annotator } from '../review/annotator.js';
|
|
19
23
|
import { shouldAutoOpenChat } from './presenter-shell.js';
|
|
20
24
|
import { installHudTelemetry } from './hud-telemetry.js';
|
|
25
|
+
import { PlanBoard, parsePlanView } from './presenter-plan.js';
|
|
26
|
+
import { claimLog, readRememberedLog, rememberLog, } from './chrome/log-memory.js';
|
|
21
27
|
const COPIED_FLASH_MS = 1600;
|
|
22
28
|
export { GlowPhase } from './presenter-config.js';
|
|
23
29
|
export { LOG_KIND, LOG_RESULT } from './chrome/presenter-log.js';
|
|
@@ -42,6 +48,7 @@ export class Presenter {
|
|
|
42
48
|
#borderMode;
|
|
43
49
|
#glowCtl;
|
|
44
50
|
#lastActionText = '';
|
|
51
|
+
#lastActor;
|
|
45
52
|
#heartbeatTimer;
|
|
46
53
|
#idleEndMs;
|
|
47
54
|
#sessionId;
|
|
@@ -51,6 +58,11 @@ export class Presenter {
|
|
|
51
58
|
#sessionActive = false;
|
|
52
59
|
#logMax;
|
|
53
60
|
#log;
|
|
61
|
+
#harnessLog;
|
|
62
|
+
#harnessRunId;
|
|
63
|
+
#harnessSteps;
|
|
64
|
+
#plan = new PlanBoard();
|
|
65
|
+
#remembered = [];
|
|
54
66
|
#logBaseMs;
|
|
55
67
|
#onControl;
|
|
56
68
|
#onHudUse;
|
|
@@ -92,16 +104,26 @@ export class Presenter {
|
|
|
92
104
|
onAnnotateToggle: () => this.#syncAnnotator(),
|
|
93
105
|
onCollapse: () => this.#syncAnnotator(),
|
|
94
106
|
onSyncNow: () => this.#onControl?.({ kind: HumanControlKind.SYNC }),
|
|
107
|
+
onSignIn: () => this.#onControl?.({ kind: HumanControlKind.SIGNIN }),
|
|
108
|
+
onHarness: (enabled) => this.#onControl?.({ kind: HumanControlKind.HARNESS, text: enabled ? 'on' : 'off' }),
|
|
109
|
+
onHarnessRun: (persona) => this.#onControl?.({
|
|
110
|
+
kind: HumanControlKind.HARNESS_RUN,
|
|
111
|
+
...(persona === undefined ? {} : { text: persona }),
|
|
112
|
+
}),
|
|
113
|
+
onHarnessStop: () => this.#onControl?.({ kind: HumanControlKind.HARNESS_STOP }),
|
|
114
|
+
onHarnessLink: () => this.#onControl?.({ kind: HumanControlKind.HARNESS_LINK }),
|
|
95
115
|
settings: {
|
|
96
116
|
onBeforeOpen: () => {
|
|
97
117
|
if (this.#shell.isCollapsed())
|
|
98
118
|
this.#shell.expand();
|
|
99
119
|
},
|
|
100
120
|
onHideUntilRestart: () => this.#applyHideUntilRestart(),
|
|
121
|
+
onKill: () => options.onKill?.(),
|
|
101
122
|
onSettingsChange: (s) => this.#onSettingsChange(s),
|
|
102
123
|
onHarness: (enabled) => this.#onControl?.({ kind: HumanControlKind.HARNESS, text: enabled ? 'on' : 'off' }),
|
|
103
124
|
},
|
|
104
125
|
});
|
|
126
|
+
this.#shell.setProjectId(options.projectId);
|
|
105
127
|
}
|
|
106
128
|
setControlHandler(handler) {
|
|
107
129
|
this.#onControl = handler;
|
|
@@ -118,21 +140,41 @@ export class Presenter {
|
|
|
118
140
|
refilterFlows() {
|
|
119
141
|
this.#panel.refilterFlows();
|
|
120
142
|
}
|
|
143
|
+
showSdkVersion(version) {
|
|
144
|
+
if (this.#root !== undefined)
|
|
145
|
+
paintSdkVersion(this.#root, version);
|
|
146
|
+
}
|
|
121
147
|
handlePush(command) {
|
|
122
148
|
const a = command.args;
|
|
123
149
|
if (command.name === ReticleCommand.FLOWS)
|
|
124
150
|
return void this.#panel.setFlows(a['flows']);
|
|
151
|
+
if (command.name === ReticleCommand.FLOW_PROGRESS)
|
|
152
|
+
return void this.#panel.setFlowProgress(a);
|
|
153
|
+
if (command.name === ReticleCommand.PLAN) {
|
|
154
|
+
const view = parsePlanView(a);
|
|
155
|
+
if (view !== undefined)
|
|
156
|
+
this.#plan.paint(view);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
125
159
|
if (command.name === ReticleCommand.IMPACT) {
|
|
126
160
|
const snapshot = parseImpactSnapshot(a['snapshot']);
|
|
127
161
|
if (snapshot !== undefined) {
|
|
128
162
|
this.#shell.report.setSnapshot(snapshot);
|
|
129
|
-
this.#shell.
|
|
130
|
-
this.#shell.paintHarness(snapshot.harnessConfig);
|
|
163
|
+
this.#shell.paintNotices(snapshot.notices);
|
|
164
|
+
this.#shell.paintHarness(snapshot.harnessConfig, harnessGateIn(snapshot.instrumentation, snapshot.harnessConfig));
|
|
165
|
+
this.#shell.paintHarnessDrive(snapshot.harnessDrive);
|
|
166
|
+
this.#paintHarnessRun(snapshot.harnessDrive);
|
|
167
|
+
this.#shell.paintAgent(snapshot.agent);
|
|
168
|
+
this.#shell.paintImpact(snapshot.project.counts.verdicts);
|
|
169
|
+
const owner = true === snapshot.account?.signedIn ? snapshot.account.email : undefined;
|
|
170
|
+
if (claimLog(owner))
|
|
171
|
+
this.#clearRunLog();
|
|
131
172
|
this.#shell.paintAccount(snapshot.account, snapshot.dashboardUrl, {
|
|
132
173
|
projectName: snapshot.projectName,
|
|
133
174
|
dashboardUrl: snapshot.dashboardUrl,
|
|
134
175
|
verdicts: snapshot.project.counts.verdicts,
|
|
135
176
|
defects: snapshot.project.counts.failed,
|
|
177
|
+
...platformDetails(snapshot.harnessConfig, snapshot.sync),
|
|
136
178
|
});
|
|
137
179
|
}
|
|
138
180
|
return;
|
|
@@ -159,13 +201,13 @@ export class Presenter {
|
|
|
159
201
|
document.head.appendChild(style);
|
|
160
202
|
const root = document.createElement('div');
|
|
161
203
|
root.setAttribute('data-reticle-overlay', '');
|
|
162
|
-
const actStrip = `<div class="reticle-act-strip" data-liveness="idle"><span class="reticle-act-dot" aria-hidden="true"></span><span class="reticle-act">${ACT_STRIP.READY}</span
|
|
204
|
+
const actStrip = `<div class="reticle-act-strip" data-liveness="idle"><span class="reticle-act-dot" aria-hidden="true"></span><span class="reticle-act">${ACT_STRIP.READY}</span>${CONTROLS_BANNER_HTML}<span class="reticle-chip" data-reticle-chip></span><div class="reticle-act-actions">${CONTROLS_STATUS_HTML}</div></div>`;
|
|
163
205
|
root.innerHTML = `
|
|
164
206
|
${blockerHtml()}
|
|
165
207
|
<div data-reticle-glow></div>
|
|
166
208
|
<div data-reticle-cursor></div>
|
|
167
209
|
<div data-reticle-ring></div>
|
|
168
|
-
${HudShell.dockHtml(actStrip,
|
|
210
|
+
${HudShell.dockHtml(actStrip, '', DATA_RETICLE_LOG, CONTROLS_MARKS_HTML, CONTROLS_FOOT_HTML)}`;
|
|
169
211
|
document.body.appendChild(root);
|
|
170
212
|
this.#root = root;
|
|
171
213
|
this.#glow = root.querySelector('[data-reticle-glow]') ?? undefined;
|
|
@@ -179,18 +221,40 @@ export class Presenter {
|
|
|
179
221
|
this.#chatPillTime =
|
|
180
222
|
root.querySelector('[data-reticle-chat-pill-time]') ?? undefined;
|
|
181
223
|
this.#log = root.querySelector(`[${DATA_RETICLE_LOG}]`) ?? undefined;
|
|
224
|
+
this.#harnessLog = root.querySelector(`[${HARNESS_LOG_ATTR}]`) ?? undefined;
|
|
182
225
|
this.#chip = root.querySelector('[data-reticle-chip]') ?? undefined;
|
|
183
226
|
this.#tally = root.querySelector('[data-reticle-tally]') ?? undefined;
|
|
184
227
|
this.#shell.mount(root);
|
|
185
228
|
syncPageBlocker(root, getPresenterSettings(), false);
|
|
186
229
|
this.#glowCtl.setElements(this.#glow, this.#cursor);
|
|
187
230
|
this.#panel.mount(root, this.#glow);
|
|
231
|
+
this.#plan.mount(root);
|
|
188
232
|
if (this.#onHudUse !== undefined) {
|
|
189
233
|
this.#hudTelemetryTeardown = installHudTelemetry(document, root, this.#onHudUse);
|
|
190
234
|
}
|
|
191
235
|
this.setMode(this.#mode);
|
|
236
|
+
this.#restoreLog();
|
|
192
237
|
this.#renderTally();
|
|
193
238
|
}
|
|
239
|
+
#restoreLog() {
|
|
240
|
+
if (this.#log === undefined || 0 < this.#remembered.length)
|
|
241
|
+
return;
|
|
242
|
+
for (const row of readRememberedLog().slice(-this.#logMax)) {
|
|
243
|
+
for (const log of this.#logsFor(row.actor, true === row.summary)) {
|
|
244
|
+
const handle = appendLogRow(log, row.kind, row.text, row.ts, this.#logMax, row.actor);
|
|
245
|
+
if (row.result !== undefined)
|
|
246
|
+
handle.result(row.result);
|
|
247
|
+
}
|
|
248
|
+
this.#logBaseMs = this.#now() - row.at;
|
|
249
|
+
this.#runLog.push({
|
|
250
|
+
at: row.at,
|
|
251
|
+
kind: row.kind,
|
|
252
|
+
text: row.text,
|
|
253
|
+
...(row.result === undefined ? {} : { result: row.result }),
|
|
254
|
+
});
|
|
255
|
+
this.#remembered.push(row);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
194
258
|
bindAnnotator(annotator) {
|
|
195
259
|
this.#annotator = annotator;
|
|
196
260
|
const root = this.#root;
|
|
@@ -207,9 +271,10 @@ export class Presenter {
|
|
|
207
271
|
let marks = annotator.markCount;
|
|
208
272
|
chrome.onCount = (n) => {
|
|
209
273
|
if (0 === marks && n > 0)
|
|
210
|
-
this.#shell.
|
|
274
|
+
this.#shell.openView('annotations');
|
|
211
275
|
marks = n;
|
|
212
276
|
};
|
|
277
|
+
chrome.onMarksChange = (items) => this.#shell.paintAnnotations(items);
|
|
213
278
|
if (copy instanceof HTMLElement) {
|
|
214
279
|
copy.addEventListener('click', (e) => {
|
|
215
280
|
e.stopPropagation();
|
|
@@ -253,6 +318,9 @@ export class Presenter {
|
|
|
253
318
|
this.#sessionActive = false;
|
|
254
319
|
this.#logBaseMs = undefined;
|
|
255
320
|
this.#log = undefined;
|
|
321
|
+
this.#harnessLog = undefined;
|
|
322
|
+
this.#remembered = [];
|
|
323
|
+
rememberLog([]);
|
|
256
324
|
this.#root?.remove();
|
|
257
325
|
document.querySelectorAll('style[data-reticle-overlay]').forEach((s) => s.remove());
|
|
258
326
|
this.#root = undefined;
|
|
@@ -283,8 +351,9 @@ export class Presenter {
|
|
|
283
351
|
const dock = this.#root?.querySelector('[data-reticle-dock]');
|
|
284
352
|
dock?.setAttribute(DATA_ON, GLOW_ON);
|
|
285
353
|
this.#hud?.setAttribute(DATA_ON, GLOW_ON);
|
|
286
|
-
this.#lastActionText =
|
|
354
|
+
this.#lastActionText = UNREACHABLE_HEADLINE;
|
|
287
355
|
this.#paintActStrip(this.#lastActionText, true);
|
|
356
|
+
this.#actLine?.setAttribute('title', unreachableMessage(url, attempts));
|
|
288
357
|
if (shouldAutoOpenChat(getPresenterSettings().autoOpenChat))
|
|
289
358
|
this.#shell.openChat();
|
|
290
359
|
}
|
|
@@ -362,9 +431,25 @@ export class Presenter {
|
|
|
362
431
|
this.#lastActionText = text;
|
|
363
432
|
this.#paintActStrip(text, false);
|
|
364
433
|
}
|
|
365
|
-
#
|
|
366
|
-
if (
|
|
434
|
+
#paintHarnessRun(drive) {
|
|
435
|
+
if (drive !== undefined && drive.runId !== this.#harnessRunId) {
|
|
436
|
+
this.#harnessRunId = drive.runId;
|
|
437
|
+
if (this.#harnessLog !== undefined)
|
|
438
|
+
clearLogRows(this.#harnessLog);
|
|
439
|
+
}
|
|
440
|
+
const was = this.#harnessSteps;
|
|
441
|
+
this.#harnessSteps = drive?.steps;
|
|
442
|
+
if (drive !== undefined)
|
|
443
|
+
this.#paintActStrip(this.#lastActionText, false);
|
|
444
|
+
else if (was !== undefined)
|
|
445
|
+
this.#paintActStrip(ACT_STRIP.READY, true);
|
|
446
|
+
}
|
|
447
|
+
#paintActStrip(raw, idle) {
|
|
448
|
+
const text = this.#harnessSteps === undefined ? raw : ACT_STRIP.harnessTesting(this.#harnessSteps);
|
|
449
|
+
if (this.#actLine !== undefined) {
|
|
367
450
|
this.#actLine.textContent = text;
|
|
451
|
+
this.#actLine.removeAttribute('title');
|
|
452
|
+
}
|
|
368
453
|
const liveness = idle ? 'idle' : 'active';
|
|
369
454
|
if (this.#actStrip !== undefined)
|
|
370
455
|
this.#actStrip.setAttribute('data-liveness', liveness);
|
|
@@ -400,6 +485,12 @@ export class Presenter {
|
|
|
400
485
|
return;
|
|
401
486
|
if ('' === this.#lastActionText)
|
|
402
487
|
return;
|
|
488
|
+
if (this.#harnessSteps !== undefined)
|
|
489
|
+
return;
|
|
490
|
+
if (LOG_ACTOR.HARNESS === this.#lastActor) {
|
|
491
|
+
this.#paintActStrip(ACT_STRIP.READY, true);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
403
494
|
const since = ACT_STRIP.SINCE_LAST;
|
|
404
495
|
this.#paintActStrip(`${ACT_STRIP.PLANNING_PREFIX}${humanDuration(idleMs)}${since}`, true);
|
|
405
496
|
if (this.#chatPillTime !== undefined)
|
|
@@ -414,6 +505,37 @@ export class Presenter {
|
|
|
414
505
|
this.#heartbeatTimer = undefined;
|
|
415
506
|
}
|
|
416
507
|
}
|
|
508
|
+
placeHud(visibility, corner) {
|
|
509
|
+
const root = this.#root;
|
|
510
|
+
if (root === undefined)
|
|
511
|
+
return [];
|
|
512
|
+
const applied = [];
|
|
513
|
+
if (HudVisibility.REMOVED === visibility) {
|
|
514
|
+
this.destroy();
|
|
515
|
+
return [visibility];
|
|
516
|
+
}
|
|
517
|
+
if (HudVisibility.HIDDEN === visibility)
|
|
518
|
+
root.setAttribute(HIDDEN_UNTIL_RESTART_ATTR, '1');
|
|
519
|
+
if (HudVisibility.SHOWN === visibility)
|
|
520
|
+
root.removeAttribute(HIDDEN_UNTIL_RESTART_ATTR);
|
|
521
|
+
if (visibility !== undefined)
|
|
522
|
+
applied.push(visibility);
|
|
523
|
+
const dock = root.querySelector(`[${DOCK_ATTR}]`);
|
|
524
|
+
if (corner !== undefined && dock instanceof HTMLElement) {
|
|
525
|
+
if (HudCorner.BOTTOM_RIGHT === corner)
|
|
526
|
+
resetHudDockPosition(dock);
|
|
527
|
+
else {
|
|
528
|
+
const box = hudLayoutBox(dock);
|
|
529
|
+
const left = corner.endsWith('left') ? 0 : window.innerWidth;
|
|
530
|
+
const top = corner.startsWith('top') ? 0 : window.innerHeight;
|
|
531
|
+
const at = clampHudPosition(left, top, box.width, box.height, window.innerWidth, window.innerHeight);
|
|
532
|
+
applyHudPosition(dock, at.left, at.top);
|
|
533
|
+
}
|
|
534
|
+
applied.push(corner);
|
|
535
|
+
scheduleSyncDockLayout(dock, root);
|
|
536
|
+
}
|
|
537
|
+
return applied;
|
|
538
|
+
}
|
|
417
539
|
setIdleEndMs(ms) {
|
|
418
540
|
if (!Number.isFinite(ms))
|
|
419
541
|
return;
|
|
@@ -446,9 +568,13 @@ export class Presenter {
|
|
|
446
568
|
}
|
|
447
569
|
#clearRunLog() {
|
|
448
570
|
this.#runLog = [];
|
|
571
|
+
this.#remembered = [];
|
|
572
|
+
rememberLog([]);
|
|
449
573
|
this.#tallied = { passes: 0, fails: 0 };
|
|
450
574
|
if (this.#log !== undefined)
|
|
451
575
|
clearLogRows(this.#log);
|
|
576
|
+
if (this.#harnessLog !== undefined)
|
|
577
|
+
clearLogRows(this.#harnessLog);
|
|
452
578
|
this.#renderTally();
|
|
453
579
|
}
|
|
454
580
|
#applyHideUntilRestart() {
|
|
@@ -463,14 +589,19 @@ export class Presenter {
|
|
|
463
589
|
else {
|
|
464
590
|
this.#renderTally();
|
|
465
591
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
592
|
+
this.#syncAnnotator();
|
|
593
|
+
}
|
|
594
|
+
#logsFor(actor, summary) {
|
|
595
|
+
const agent = this.#log;
|
|
596
|
+
const harness = this.#harnessLog;
|
|
597
|
+
if (LOG_ACTOR.HARNESS !== actor || harness === undefined)
|
|
598
|
+
return agent === undefined ? [] : [agent];
|
|
599
|
+
return summary && agent !== undefined ? [agent, harness] : [harness];
|
|
470
600
|
}
|
|
471
|
-
log(kind, text, result) {
|
|
601
|
+
log(kind, text, result, actor, summary = false) {
|
|
472
602
|
const ms = this.#now();
|
|
473
603
|
this.#glowCtl.markActivity(ms);
|
|
604
|
+
this.#lastActor = actor;
|
|
474
605
|
if (this.#log === undefined)
|
|
475
606
|
return undefined;
|
|
476
607
|
const trimmed = text.trim();
|
|
@@ -484,9 +615,23 @@ export class Presenter {
|
|
|
484
615
|
while (this.#runLog.length > this.#logMax)
|
|
485
616
|
this.#runLog.shift();
|
|
486
617
|
const ts = formatElapsed(ms - this.#logBaseMs);
|
|
487
|
-
const
|
|
618
|
+
const handles = this.#logsFor(actor, summary).map((log) => appendLogRow(log, kind, trimmed, ts, this.#logMax, actor));
|
|
619
|
+
const handle = { result: (r) => handles.forEach((h) => h.result(r)) };
|
|
488
620
|
if (result !== undefined)
|
|
489
621
|
handle.result(result);
|
|
622
|
+
const kept = {
|
|
623
|
+
kind,
|
|
624
|
+
text: trimmed,
|
|
625
|
+
ts,
|
|
626
|
+
at: ms - this.#logBaseMs,
|
|
627
|
+
...(actor === undefined ? {} : { actor }),
|
|
628
|
+
...(summary ? { summary: true } : {}),
|
|
629
|
+
...(result === undefined ? {} : { result }),
|
|
630
|
+
};
|
|
631
|
+
this.#remembered.push(kept);
|
|
632
|
+
while (this.#remembered.length > this.#logMax)
|
|
633
|
+
this.#remembered.shift();
|
|
634
|
+
rememberLog(this.#remembered);
|
|
490
635
|
if (this.#shell.isCollapsed())
|
|
491
636
|
this.#shell.pulseFab(true);
|
|
492
637
|
this.#renderTally();
|
|
@@ -494,6 +639,8 @@ export class Presenter {
|
|
|
494
639
|
result: (r) => {
|
|
495
640
|
handle.result(r);
|
|
496
641
|
entry.result = r;
|
|
642
|
+
kept.result = r;
|
|
643
|
+
rememberLog(this.#remembered);
|
|
497
644
|
this.#renderTally();
|
|
498
645
|
},
|
|
499
646
|
};
|
|
@@ -505,14 +652,16 @@ export class Presenter {
|
|
|
505
652
|
}
|
|
506
653
|
this.#tallied = renderTally(this.#tally, this.#runLog, this.#tallied);
|
|
507
654
|
}
|
|
508
|
-
narrate(text, level = 'info') {
|
|
655
|
+
narrate(text, level = 'info', actor = LOG_ACTOR.AGENT, summary = false) {
|
|
509
656
|
const line = 'info' === level ? text : `[${level}] ${text}`;
|
|
510
|
-
return this.log(LOG_KIND.NARRATION, line);
|
|
657
|
+
return this.log(LOG_KIND.NARRATION, line, undefined, actor, summary);
|
|
511
658
|
}
|
|
512
659
|
#pruneLog() {
|
|
513
660
|
if (this.#log === undefined)
|
|
514
661
|
return;
|
|
515
662
|
trimLogRows(this.#log, this.#logMax);
|
|
663
|
+
if (this.#harnessLog !== undefined)
|
|
664
|
+
trimLogRows(this.#harnessLog, this.#logMax);
|
|
516
665
|
}
|
|
517
666
|
setThrottled(throttled) {
|
|
518
667
|
this.#root?.setAttribute(THROTTLED_ATTR, throttled ? '1' : '0');
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { isLastSlide } from './tour-view.js';
|
|
2
|
-
|
|
2
|
+
import { TourAnchor } from '@reticlehq/core/tour';
|
|
3
|
+
import { TOUR_SEEN_KEY_PREFIX } from '../../storage-keys.js';
|
|
4
|
+
export { TOUR_SEEN_KEY_PREFIX };
|
|
5
|
+
export declare const HUD_CONTROL_SELECTORS: Readonly<Partial<Record<TourAnchor, string>>>;
|
|
3
6
|
export declare const tourSeenKey: (projectId: string) => string;
|
|
4
7
|
export interface TourStorage {
|
|
5
8
|
getItem: (key: string) => string | null;
|
|
@@ -2,7 +2,8 @@ import { COPIED_LABEL, COPY_FLASH_MS, COPY_LABEL, COPY_MANUAL_LABEL, TOUR_ATTR,
|
|
|
2
2
|
import { TourAnchor } from '@reticlehq/core/tour';
|
|
3
3
|
import { RETICLE_URL_PARAM } from '@reticlehq/core';
|
|
4
4
|
import { appModalOpen } from '../../dom/dom-ignore.js';
|
|
5
|
-
|
|
5
|
+
import { TOUR_SEEN_KEY_PREFIX } from '../../storage-keys.js';
|
|
6
|
+
export { TOUR_SEEN_KEY_PREFIX };
|
|
6
7
|
const APP_SELECTORS = ['main', '#root', '#app'];
|
|
7
8
|
const HUD_PARTS = ['[data-reticle-hud]', '[data-reticle-chat-panel]'];
|
|
8
9
|
function unionOfVisible(doc, selectors) {
|
|
@@ -23,10 +24,11 @@ function unionOfVisible(doc, selectors) {
|
|
|
23
24
|
return undefined;
|
|
24
25
|
return { left, top, width: right - left, height: bottom - top };
|
|
25
26
|
}
|
|
26
|
-
const HUD_CONTROL_SELECTORS = {
|
|
27
|
+
export const HUD_CONTROL_SELECTORS = {
|
|
27
28
|
[TourAnchor.HUD_CHAT]: '[data-reticle-chat-toggle]',
|
|
28
|
-
[TourAnchor.
|
|
29
|
-
[TourAnchor.
|
|
29
|
+
[TourAnchor.HUD_FLOWS]: '[data-reticle-chat-view-btn="flows"]',
|
|
30
|
+
[TourAnchor.HUD_ANNOTATE]: '[data-reticle-chat-view-btn="annotations"]',
|
|
31
|
+
[TourAnchor.HUD_IMPACT]: '[data-reticle-chat-impact]',
|
|
30
32
|
[TourAnchor.HUD_SETTINGS]: '[data-reticle-settings-btn]',
|
|
31
33
|
};
|
|
32
34
|
function anchorBox(doc, anchor) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readTestId } from '../dom/addressing/testid-attr.js';
|
|
1
2
|
import { ActionType, AnchorKind, AnnotationKind, DEGRADED_ANCHOR_ROLE, EventType, FLOW_FILE_VERSION, FlowStepTool, RecorderPhase, PredicateKind, } from '@reticlehq/core';
|
|
2
3
|
import { REDACTED_VALUE } from '@reticlehq/core';
|
|
3
4
|
import { sourceFromDom } from '../dom/addressing/source.js';
|
|
@@ -9,7 +10,6 @@ export const RECORDER_EMPTY_MSG = 'recorded 0 steps';
|
|
|
9
10
|
const STATUS_RECORDING = 'recording…';
|
|
10
11
|
const STATUS_IDLE = 'ready';
|
|
11
12
|
const STATUS_ANNOTATE = 'pick an annotation';
|
|
12
|
-
const TESTID_ATTR = 'data-testid';
|
|
13
13
|
const TOOL = FlowStepTool.ACT;
|
|
14
14
|
const BUTTON_LABEL = {
|
|
15
15
|
record: 'Record',
|
|
@@ -31,7 +31,7 @@ const NEEDS_SIGNAL = new Set([
|
|
|
31
31
|
]);
|
|
32
32
|
const DEFAULT_NAME = 'recorded-flow';
|
|
33
33
|
export function anchorFor(el) {
|
|
34
|
-
const testid = el
|
|
34
|
+
const testid = readTestId(el);
|
|
35
35
|
if (testid !== null && testid.length > 0) {
|
|
36
36
|
return { anchor: { kind: AnchorKind.TESTID, value: testid }, degraded: false };
|
|
37
37
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const TESTID_SELECTOR = `[${TESTID_ATTR}]`;
|
|
1
|
+
import { getTestIdAttr, testIdSelector } from '../dom/addressing/testid-attr.js';
|
|
3
2
|
export const MAX_AUTO_TESTIDS = 200;
|
|
4
3
|
const RETICLE_OWN_PREFIX = 'reticle-';
|
|
5
4
|
export function domTestids(doc) {
|
|
@@ -7,13 +6,13 @@ export function domTestids(doc) {
|
|
|
7
6
|
const seen = new Set();
|
|
8
7
|
let nodes;
|
|
9
8
|
try {
|
|
10
|
-
nodes = doc.querySelectorAll(
|
|
9
|
+
nodes = doc.querySelectorAll(testIdSelector());
|
|
11
10
|
}
|
|
12
11
|
catch {
|
|
13
12
|
return out;
|
|
14
13
|
}
|
|
15
14
|
for (let i = 0; i < nodes.length && out.length < MAX_AUTO_TESTIDS; i += 1) {
|
|
16
|
-
const value = nodes[i]?.getAttribute(
|
|
15
|
+
const value = nodes[i]?.getAttribute(getTestIdAttr());
|
|
17
16
|
if (null === value || undefined === value)
|
|
18
17
|
continue;
|
|
19
18
|
const trimmed = value.trim();
|
|
@@ -25,9 +25,13 @@ export const SERVED_COMMANDS = [
|
|
|
25
25
|
ReticleCommand.PRESENTER,
|
|
26
26
|
ReticleCommand.IMPACT,
|
|
27
27
|
ReticleCommand.CAPTURE,
|
|
28
|
+
ReticleCommand.RENDER,
|
|
28
29
|
ReticleCommand.NAVIGATE,
|
|
29
30
|
ReticleCommand.REFRESH,
|
|
30
31
|
ReticleCommand.FLOWS,
|
|
32
|
+
ReticleCommand.FLOW_PROGRESS,
|
|
33
|
+
ReticleCommand.PLAN,
|
|
34
|
+
ReticleCommand.MARKERS,
|
|
31
35
|
];
|
|
32
36
|
export function declaredCommands() {
|
|
33
37
|
return [...SERVED_COMMANDS];
|