haltija 1.3.2 → 1.3.4

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haltija-desktop",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "private": true,
5
5
  "description": "Haltija Desktop - God Mode Browser for AI Agents",
6
6
  "homepage": "https://github.com/tonioloewald/haltija",
@@ -46,7 +46,7 @@
46
46
  });
47
47
 
48
48
  // src/version.ts
49
- var VERSION = "1.3.2";
49
+ var VERSION = "1.3.4";
50
50
 
51
51
  // src/text-selector.ts
52
52
  var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
@@ -598,13 +598,13 @@
598
598
  }
599
599
  function resolveRefOrSelector(ref, selector) {
600
600
  if (ref) {
601
- const result2 = refRegistry.resolveWithStatus(ref);
602
- if (result2.element) {
601
+ const result = refRegistry.resolveWithStatus(ref);
602
+ if (result.element) {
603
603
  stats.refsResolved++;
604
- return { element: result2.element, targetDesc: `@${ref}` };
604
+ return { element: result.element, targetDesc: `@${ref}` };
605
605
  }
606
606
  stats.refsStale++;
607
- const errorMsg = result2.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result2.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
607
+ const errorMsg = result.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
608
608
  return { element: null, targetDesc: `@${ref}`, error: errorMsg };
609
609
  }
610
610
  if (selector) {
@@ -615,13 +615,13 @@
615
615
  }
616
616
  function resolveRefOrSelectorAll(ref, selector) {
617
617
  if (ref) {
618
- const result2 = refRegistry.resolveWithStatus(ref);
619
- if (result2.element) {
618
+ const result = refRegistry.resolveWithStatus(ref);
619
+ if (result.element) {
620
620
  stats.refsResolved++;
621
- return { elements: [result2.element], targetDesc: `@${ref}` };
621
+ return { elements: [result.element], targetDesc: `@${ref}` };
622
622
  }
623
623
  stats.refsStale++;
624
- const errorMsg = result2.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result2.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
624
+ const errorMsg = result.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
625
625
  return { elements: [], targetDesc: `@${ref}`, error: errorMsg };
626
626
  }
627
627
  if (selector) {
@@ -1761,6 +1761,7 @@
1761
1761
  displayStream = null;
1762
1762
  displayVideo = null;
1763
1763
  isActive = true;
1764
+ visibilityHandler = null;
1764
1765
  homeLeft = 0;
1765
1766
  homeBottom = 16;
1766
1767
  headless = false;
@@ -1952,6 +1953,16 @@
1952
1953
  }
1953
1954
  this.interceptConsole();
1954
1955
  this.interceptDialogs();
1956
+ if (typeof document !== "undefined") {
1957
+ this.visibilityHandler = () => {
1958
+ if (document.visibilityState === "hidden") {
1959
+ this.deactivate();
1960
+ } else {
1961
+ this.activate();
1962
+ }
1963
+ };
1964
+ document.addEventListener("visibilitychange", this.visibilityHandler);
1965
+ }
1955
1966
  this.connect();
1956
1967
  }
1957
1968
  disconnectedCallback() {
@@ -1962,6 +1973,10 @@
1962
1973
  this.clearEventWatchers();
1963
1974
  this.stopMutationWatch();
1964
1975
  this.stopScreenCapture();
1976
+ if (this.visibilityHandler && typeof document !== "undefined") {
1977
+ document.removeEventListener("visibilitychange", this.visibilityHandler);
1978
+ this.visibilityHandler = null;
1979
+ }
1965
1980
  }
1966
1981
  attributeChangedCallback(name, _old, value) {
1967
1982
  if (name === "server") {
@@ -2855,8 +2870,8 @@
2855
2870
  headers: { "Content-Type": "application/json" },
2856
2871
  body: JSON.stringify({ action: "start", window: this.windowId })
2857
2872
  });
2858
- const result2 = await response.json();
2859
- if (result2.success) {
2873
+ const result = await response.json();
2874
+ if (result.success) {
2860
2875
  this.isRecording = true;
2861
2876
  this.serverManagedRecording = true;
2862
2877
  this.recordingStartTime = Date.now();
@@ -2868,7 +2883,7 @@
2868
2883
  this.updateRecordingUI(true);
2869
2884
  console.log("[Haltija] Recording started (server-managed)");
2870
2885
  } else {
2871
- console.error("[Haltija] Failed to start recording:", result2.error);
2886
+ console.error("[Haltija] Failed to start recording:", result.error);
2872
2887
  }
2873
2888
  } catch (err) {
2874
2889
  console.error("[Haltija] Failed to start recording:", err);
@@ -2883,10 +2898,10 @@
2883
2898
  headers: { "Content-Type": "application/json" },
2884
2899
  body: JSON.stringify({ action: "stop", window: this.windowId })
2885
2900
  });
2886
- const result2 = await response.json();
2887
- if (result2.success && result2.data) {
2888
- this.recordingEvents = result2.data.events || [];
2889
- this.recordingStartTime = result2.data.startTime || this.recordingStartTime;
2901
+ const result = await response.json();
2902
+ if (result.success && result.data) {
2903
+ this.recordingEvents = result.data.events || [];
2904
+ this.recordingStartTime = result.data.startTime || this.recordingStartTime;
2890
2905
  const recordingId = `rec_${this.recordingStartTime}_${Math.random().toString(36).slice(2, 8)}`;
2891
2906
  this.lastRecordingId = recordingId;
2892
2907
  console.log(`[Haltija] Recording stopped (${this.recordingEvents.length} events)`);
@@ -3199,15 +3214,15 @@
3199
3214
  headers: { "Content-Type": "application/json" },
3200
3215
  body: JSON.stringify({ description, agentId })
3201
3216
  });
3202
- const result2 = await response.json();
3203
- if (result2.error) {
3217
+ const result = await response.json();
3218
+ if (result.error) {
3204
3219
  if (successMsg) {
3205
- successMsg.textContent = `⚠️ ${result2.error}`;
3220
+ successMsg.textContent = `⚠️ ${result.error}`;
3206
3221
  successMsg.style.color = "#f59e0b";
3207
3222
  }
3208
3223
  } else {
3209
3224
  if (successMsg) {
3210
- successMsg.textContent = `✓ Sent to ${agentName}${result2.interrupted ? " (interrupted)" : ""}`;
3225
+ successMsg.textContent = `✓ Sent to ${agentName}${result.interrupted ? " (interrupted)" : ""}`;
3211
3226
  successMsg.style.color = "#22c55e";
3212
3227
  }
3213
3228
  setTimeout(() => this.closeTestModal(), 1500);
@@ -3738,13 +3753,13 @@
3738
3753
  const haltija = window.haltija;
3739
3754
  if (haltija?.openAgentTab) {
3740
3755
  newAgentText.textContent = "Creating...";
3741
- const result2 = await haltija.openAgentTab();
3742
- if (result2?.shellId) {
3756
+ const result = await haltija.openAgentTab();
3757
+ if (result?.shellId) {
3743
3758
  await new Promise((r) => setTimeout(r, 300));
3744
3759
  if (type === "selection") {
3745
- this.sendSelectionToAgent(result2.shellId, result2.name || "agent");
3760
+ this.sendSelectionToAgent(result.shellId, result.name || "agent");
3746
3761
  } else if (type === "recording") {
3747
- this.sendRecordingToAgent(result2.shellId, result2.name || "agent");
3762
+ this.sendRecordingToAgent(result.shellId, result.name || "agent");
3748
3763
  }
3749
3764
  } else {
3750
3765
  console.error(`${LOG_PREFIX} Failed to create agent tab`);
@@ -3813,8 +3828,8 @@ ${elementSummary}${moreText}`;
3813
3828
  context: `selection from ${window.location.host}`
3814
3829
  })
3815
3830
  });
3816
- const result2 = await response.json();
3817
- if (result2.sent) {
3831
+ const result = await response.json();
3832
+ if (result.sent) {
3818
3833
  this.clearSelection();
3819
3834
  console.log(`${LOG_PREFIX} Selection sent to ${agentName}`);
3820
3835
  }
@@ -5100,6 +5115,7 @@ ${elementSummary}${moreText}`;
5100
5115
  this.state = "connected";
5101
5116
  this.show();
5102
5117
  const windowType = window.opener ? "popup" : window.parent !== window ? "iframe" : "tab";
5118
+ this.isActive = typeof document === "undefined" || document.visibilityState !== "hidden";
5103
5119
  this.send("system", "connected", {
5104
5120
  windowId: this.windowId,
5105
5121
  browserId: this.browserId,
@@ -5328,11 +5344,11 @@ ${elementSummary}${moreText}`;
5328
5344
  this.respond(msg2.id, false, undefined, "Video capture requires the Haltija Desktop app. Run: npx haltija@latest -f");
5329
5345
  return;
5330
5346
  }
5331
- haltija.startVideoCapture({ maxDuration: payload2.maxDuration }).then((result2) => {
5332
- if (result2.success) {
5333
- this.respond(msg2.id, true, { recordingId: result2.recordingId });
5347
+ haltija.startVideoCapture({ maxDuration: payload2.maxDuration }).then((result) => {
5348
+ if (result.success) {
5349
+ this.respond(msg2.id, true, { recordingId: result.recordingId });
5334
5350
  } else {
5335
- this.respond(msg2.id, false, undefined, result2.error || "Failed to start video");
5351
+ this.respond(msg2.id, false, undefined, result.error || "Failed to start video");
5336
5352
  }
5337
5353
  }).catch((err) => {
5338
5354
  this.respond(msg2.id, false, undefined, `Failed to start video: ${err.message}`);
@@ -5342,11 +5358,11 @@ ${elementSummary}${moreText}`;
5342
5358
  this.respond(msg2.id, false, undefined, "Video capture requires the Haltija Desktop app. Run: npx haltija@latest -f");
5343
5359
  return;
5344
5360
  }
5345
- haltija.stopVideoCapture().then((result2) => {
5346
- if (result2.success) {
5347
- this.respond(msg2.id, true, { path: result2.path, duration: result2.duration, size: result2.size, format: result2.format });
5361
+ haltija.stopVideoCapture().then((result) => {
5362
+ if (result.success) {
5363
+ this.respond(msg2.id, true, { path: result.path, duration: result.duration, size: result.size, format: result.format });
5348
5364
  } else {
5349
- this.respond(msg2.id, false, undefined, result2.error || "Failed to stop video");
5365
+ this.respond(msg2.id, false, undefined, result.error || "Failed to stop video");
5350
5366
  }
5351
5367
  }).catch((err) => {
5352
5368
  this.respond(msg2.id, false, undefined, `Failed to stop video: ${err.message}`);
@@ -5356,8 +5372,8 @@ ${elementSummary}${moreText}`;
5356
5372
  this.respond(msg2.id, true, { recording: false });
5357
5373
  return;
5358
5374
  }
5359
- haltija.videoStatus().then((result2) => {
5360
- this.respond(msg2.id, true, result2);
5375
+ haltija.videoStatus().then((result) => {
5376
+ this.respond(msg2.id, true, result);
5361
5377
  }).catch(() => {
5362
5378
  this.respond(msg2.id, true, { recording: false });
5363
5379
  });
@@ -5374,8 +5390,8 @@ ${elementSummary}${moreText}`;
5374
5390
  this.respond(msg2.id, false, undefined, notAvailable);
5375
5391
  return;
5376
5392
  }
5377
- haltija.networkWatch(payload2 || {}).then((result2) => {
5378
- this.respond(msg2.id, result2.success !== false, result2);
5393
+ haltija.networkWatch(payload2 || {}).then((result) => {
5394
+ this.respond(msg2.id, result.success !== false, result);
5379
5395
  }).catch((err) => {
5380
5396
  this.respond(msg2.id, false, undefined, err.message);
5381
5397
  });
@@ -5384,8 +5400,8 @@ ${elementSummary}${moreText}`;
5384
5400
  this.respond(msg2.id, false, undefined, notAvailable);
5385
5401
  return;
5386
5402
  }
5387
- haltija.networkUnwatch().then((result2) => {
5388
- this.respond(msg2.id, true, result2);
5403
+ haltija.networkUnwatch().then((result) => {
5404
+ this.respond(msg2.id, true, result);
5389
5405
  }).catch((err) => {
5390
5406
  this.respond(msg2.id, false, undefined, err.message);
5391
5407
  });
@@ -5394,8 +5410,8 @@ ${elementSummary}${moreText}`;
5394
5410
  this.respond(msg2.id, false, undefined, notAvailable);
5395
5411
  return;
5396
5412
  }
5397
- haltija.networkLog(payload2 || {}).then((result2) => {
5398
- this.respond(msg2.id, true, result2);
5413
+ haltija.networkLog(payload2 || {}).then((result) => {
5414
+ this.respond(msg2.id, true, result);
5399
5415
  }).catch((err) => {
5400
5416
  this.respond(msg2.id, false, undefined, err.message);
5401
5417
  });
@@ -5404,8 +5420,8 @@ ${elementSummary}${moreText}`;
5404
5420
  this.respond(msg2.id, false, undefined, notAvailable);
5405
5421
  return;
5406
5422
  }
5407
- haltija.networkStats().then((result2) => {
5408
- this.respond(msg2.id, true, result2);
5423
+ haltija.networkStats().then((result) => {
5424
+ this.respond(msg2.id, true, result);
5409
5425
  }).catch((err) => {
5410
5426
  this.respond(msg2.id, false, undefined, err.message);
5411
5427
  });
@@ -5414,8 +5430,8 @@ ${elementSummary}${moreText}`;
5414
5430
  this.respond(msg2.id, false, undefined, notAvailable);
5415
5431
  return;
5416
5432
  }
5417
- haltija.networkClear().then((result2) => {
5418
- this.respond(msg2.id, true, result2);
5433
+ haltija.networkClear().then((result) => {
5434
+ this.respond(msg2.id, true, result);
5419
5435
  }).catch((err) => {
5420
5436
  this.respond(msg2.id, false, undefined, err.message);
5421
5437
  });
@@ -5861,9 +5877,9 @@ ${elementSummary}${moreText}`;
5861
5877
  try {
5862
5878
  const capturePromise = targetSelector ? haltija.captureElement(targetSelector) : haltija.capturePage();
5863
5879
  const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve({ success: false, error: "Screenshot capture timed out after 10s" }), 1e4));
5864
- const result2 = await Promise.race([capturePromise, timeoutPromise]);
5865
- if (result2?.success && result2.data) {
5866
- const converted = await convertFormat(result2.data);
5880
+ const result = await Promise.race([capturePromise, timeoutPromise]);
5881
+ if (result?.success && result.data) {
5882
+ const converted = await convertFormat(result.data);
5867
5883
  this.respond(msg2.id, true, {
5868
5884
  image: converted.image,
5869
5885
  viewport,
@@ -5873,8 +5889,8 @@ ${elementSummary}${moreText}`;
5873
5889
  source: "electron"
5874
5890
  });
5875
5891
  return;
5876
- } else if (result2 && !result2.success) {
5877
- this.respond(msg2.id, false, null, result2.error || "Electron capture failed");
5892
+ } else if (result && !result.success) {
5893
+ this.respond(msg2.id, false, null, result.error || "Electron capture failed");
5878
5894
  return;
5879
5895
  }
5880
5896
  } catch (err) {
@@ -5945,14 +5961,29 @@ ${elementSummary}${moreText}`;
5945
5961
  this.respond(msg2.id, true);
5946
5962
  }
5947
5963
  }
5948
- async handleEvalMessage(msg) {
5964
+ async handleEvalMessage(msg2) {
5949
5965
  try {
5950
- const result = eval(msg.payload.code);
5966
+ const result = this.evalCode(msg2.payload.code);
5951
5967
  const resolved = result instanceof Promise ? await result : result;
5952
- this.respond(msg.id, true, resolved);
5968
+ this.respond(msg2.id, true, resolved);
5969
+ } catch (err) {
5970
+ this.respond(msg2.id, false, null, err.message);
5971
+ }
5972
+ }
5973
+ evalCode(code) {
5974
+ try {
5975
+ return eval(code);
5976
+ } catch (err) {
5977
+ if (!(err instanceof SyntaxError) || !/\b(await|return)\b/.test(code))
5978
+ throw err;
5979
+ }
5980
+ try {
5981
+ return eval(`(async () => (${code}))()`);
5953
5982
  } catch (err) {
5954
- this.respond(msg.id, false, null, err.message);
5983
+ if (!(err instanceof SyntaxError))
5984
+ throw err;
5955
5985
  }
5986
+ return eval(`(async () => { ${code} })()`);
5956
5987
  }
5957
5988
  async handleFetchMessage(msg2) {
5958
5989
  const { url } = msg2.payload;
@@ -6030,14 +6061,14 @@ ${elementSummary}${moreText}`;
6030
6061
  let el = null;
6031
6062
  let targetDesc = "";
6032
6063
  if (ref) {
6033
- const result2 = refRegistry.resolveWithStatus(ref);
6034
- el = result2.element;
6064
+ const result = refRegistry.resolveWithStatus(ref);
6065
+ el = result.element;
6035
6066
  targetDesc = `@${ref}`;
6036
6067
  if (el) {
6037
6068
  stats.refsResolved++;
6038
6069
  } else {
6039
6070
  stats.refsStale++;
6040
- const errorMsg = result2.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result2.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
6071
+ const errorMsg = result.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
6041
6072
  this.respond(responseId, false, null, errorMsg);
6042
6073
  return;
6043
6074
  }
@@ -6382,14 +6413,14 @@ ${elementSummary}${moreText}`;
6382
6413
  let el = null;
6383
6414
  let targetDesc = "";
6384
6415
  if (payload2.ref) {
6385
- const result2 = refRegistry.resolveWithStatus(payload2.ref);
6386
- el = result2.element;
6416
+ const result = refRegistry.resolveWithStatus(payload2.ref);
6417
+ el = result.element;
6387
6418
  targetDesc = `@${payload2.ref}`;
6388
6419
  if (el) {
6389
6420
  stats.refsResolved++;
6390
6421
  } else {
6391
6422
  stats.refsStale++;
6392
- const errorMsg = result2.status === "never_assigned" ? `Ref @${payload2.ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result2.status === "removed_from_dom" ? `Ref @${payload2.ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${payload2.ref} is stale - element was garbage collected (try refreshing /tree)`;
6423
+ const errorMsg = result.status === "never_assigned" ? `Ref @${payload2.ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result.status === "removed_from_dom" ? `Ref @${payload2.ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${payload2.ref} is stale - element was garbage collected (try refreshing /tree)`;
6393
6424
  this.respond(responseId, false, null, errorMsg);
6394
6425
  return;
6395
6426
  }
@@ -6458,15 +6489,15 @@ ${elementSummary}${moreText}`;
6458
6489
  let target = null;
6459
6490
  let targetDesc = "";
6460
6491
  if (ref) {
6461
- const result2 = refRegistry.resolveWithStatus(ref);
6462
- target = result2.element;
6492
+ const result = refRegistry.resolveWithStatus(ref);
6493
+ target = result.element;
6463
6494
  targetDesc = `@${ref}`;
6464
6495
  if (target) {
6465
6496
  stats.refsResolved++;
6466
6497
  target.focus();
6467
6498
  } else {
6468
6499
  stats.refsStale++;
6469
- const errorMsg = result2.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result2.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
6500
+ const errorMsg = result.status === "never_assigned" ? `Ref @${ref} was never assigned (highest ref is @${refRegistry.getStats().highWaterMark})` : result.status === "removed_from_dom" ? `Ref @${ref} points to an element that was removed from the DOM (try refreshing /tree)` : `Ref @${ref} is stale - element was garbage collected (try refreshing /tree)`;
6470
6501
  this.respond(responseId, false, null, errorMsg);
6471
6502
  return;
6472
6503
  }
@@ -6858,9 +6889,9 @@ ${elementSummary}${moreText}`;
6858
6889
  });
6859
6890
  } else if (action2 === "result") {
6860
6891
  if (this.selectionResult) {
6861
- const result2 = this.selectionResult;
6892
+ const result = this.selectionResult;
6862
6893
  this.clearSelection();
6863
- this.respond(msg2.id, true, result2);
6894
+ this.respond(msg2.id, true, result);
6864
6895
  } else {
6865
6896
  this.respond(msg2.id, false, null, "No selection available");
6866
6897
  }
@@ -63,6 +63,8 @@ export declare const tree: EndpointDef<{
63
63
  pierceFrames?: boolean | undefined;
64
64
  compact?: boolean | undefined;
65
65
  ancestors?: boolean | undefined;
66
+ includeBox?: boolean | undefined;
67
+ mode?: string | undefined;
66
68
  window?: string | undefined;
67
69
  }>;
68
70
  export declare const query: EndpointDef<{
@@ -354,6 +356,8 @@ export declare const endpoints: {
354
356
  pierceFrames?: boolean | undefined;
355
357
  compact?: boolean | undefined;
356
358
  ancestors?: boolean | undefined;
359
+ includeBox?: boolean | undefined;
360
+ mode?: string | undefined;
357
361
  window?: string | undefined;
358
362
  }>;
359
363
  readonly query: EndpointDef<{
@@ -645,6 +649,8 @@ export declare const ALL_ENDPOINTS: (EndpointDef<{
645
649
  pierceFrames?: boolean | undefined;
646
650
  compact?: boolean | undefined;
647
651
  ancestors?: boolean | undefined;
652
+ includeBox?: boolean | undefined;
653
+ mode?: string | undefined;
648
654
  window?: string | undefined;
649
655
  }> | EndpointDef<{
650
656
  selector?: string | undefined;
@@ -20,7 +20,7 @@
20
20
  * - Option+Tab toggles visibility (but active state always shows briefly)
21
21
  * - Localhost only by default
22
22
  */
23
- export declare const VERSION = "1.3.2";
23
+ export declare const VERSION = "1.3.4";
24
24
  export declare class DevChannel extends HTMLElement {
25
25
  static get tagName(): string;
26
26
  static elementCreator(): () => DevChannel;
@@ -50,6 +50,7 @@ export declare class DevChannel extends HTMLElement {
50
50
  private displayStream;
51
51
  private displayVideo;
52
52
  private isActive;
53
+ private visibilityHandler;
53
54
  private homeLeft;
54
55
  private homeBottom;
55
56
  private headless;
@@ -267,6 +268,17 @@ export declare class DevChannel extends HTMLElement {
267
268
  private handleEventsMessage;
268
269
  private handleConsoleMessage;
269
270
  private handleEvalMessage;
271
+ /**
272
+ * Direct `eval` never inherits an async context, so top-level `await` is a
273
+ * SyntaxError no matter what encloses this call — likewise `return`. Retry
274
+ * such code inside an async IIFE: expression position first (it preserves the
275
+ * completion value), statement body second (which needs an explicit `return`).
276
+ *
277
+ * The retry is gated on the code mentioning `await`/`return` because a runtime
278
+ * SyntaxError (`JSON.parse('{')`) is indistinguishable from a parse failure
279
+ * here, and re-running would repeat any side effects the code already had.
280
+ */
281
+ private evalCode;
270
282
  private handleFetchMessage;
271
283
  private handleInteractionMessage;
272
284
  /**