haltija 1.3.3 → 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.
- package/apps/desktop/package.json +1 -1
- package/apps/desktop/resources/component.js +81 -66
- package/dist/component.d.ts +12 -1
- package/dist/component.esm.js +81 -66
- package/dist/component.js +81 -66
- package/dist/index.js +109 -70
- package/dist/server.js +109 -70
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/component.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "1.3.
|
|
2
|
+
var VERSION = "1.3.4";
|
|
3
3
|
|
|
4
4
|
// src/text-selector.ts
|
|
5
5
|
var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
|
|
@@ -551,13 +551,13 @@ function resolveSelectorAll(selector) {
|
|
|
551
551
|
}
|
|
552
552
|
function resolveRefOrSelector(ref, selector) {
|
|
553
553
|
if (ref) {
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
554
|
+
const result = refRegistry.resolveWithStatus(ref);
|
|
555
|
+
if (result.element) {
|
|
556
556
|
stats.refsResolved++;
|
|
557
|
-
return { element:
|
|
557
|
+
return { element: result.element, targetDesc: `@${ref}` };
|
|
558
558
|
}
|
|
559
559
|
stats.refsStale++;
|
|
560
|
-
const errorMsg =
|
|
560
|
+
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)`;
|
|
561
561
|
return { element: null, targetDesc: `@${ref}`, error: errorMsg };
|
|
562
562
|
}
|
|
563
563
|
if (selector) {
|
|
@@ -568,13 +568,13 @@ function resolveRefOrSelector(ref, selector) {
|
|
|
568
568
|
}
|
|
569
569
|
function resolveRefOrSelectorAll(ref, selector) {
|
|
570
570
|
if (ref) {
|
|
571
|
-
const
|
|
572
|
-
if (
|
|
571
|
+
const result = refRegistry.resolveWithStatus(ref);
|
|
572
|
+
if (result.element) {
|
|
573
573
|
stats.refsResolved++;
|
|
574
|
-
return { elements: [
|
|
574
|
+
return { elements: [result.element], targetDesc: `@${ref}` };
|
|
575
575
|
}
|
|
576
576
|
stats.refsStale++;
|
|
577
|
-
const errorMsg =
|
|
577
|
+
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)`;
|
|
578
578
|
return { elements: [], targetDesc: `@${ref}`, error: errorMsg };
|
|
579
579
|
}
|
|
580
580
|
if (selector) {
|
|
@@ -2823,8 +2823,8 @@ class DevChannel extends HTMLElement {
|
|
|
2823
2823
|
headers: { "Content-Type": "application/json" },
|
|
2824
2824
|
body: JSON.stringify({ action: "start", window: this.windowId })
|
|
2825
2825
|
});
|
|
2826
|
-
const
|
|
2827
|
-
if (
|
|
2826
|
+
const result = await response.json();
|
|
2827
|
+
if (result.success) {
|
|
2828
2828
|
this.isRecording = true;
|
|
2829
2829
|
this.serverManagedRecording = true;
|
|
2830
2830
|
this.recordingStartTime = Date.now();
|
|
@@ -2836,7 +2836,7 @@ class DevChannel extends HTMLElement {
|
|
|
2836
2836
|
this.updateRecordingUI(true);
|
|
2837
2837
|
console.log("[Haltija] Recording started (server-managed)");
|
|
2838
2838
|
} else {
|
|
2839
|
-
console.error("[Haltija] Failed to start recording:",
|
|
2839
|
+
console.error("[Haltija] Failed to start recording:", result.error);
|
|
2840
2840
|
}
|
|
2841
2841
|
} catch (err) {
|
|
2842
2842
|
console.error("[Haltija] Failed to start recording:", err);
|
|
@@ -2851,10 +2851,10 @@ class DevChannel extends HTMLElement {
|
|
|
2851
2851
|
headers: { "Content-Type": "application/json" },
|
|
2852
2852
|
body: JSON.stringify({ action: "stop", window: this.windowId })
|
|
2853
2853
|
});
|
|
2854
|
-
const
|
|
2855
|
-
if (
|
|
2856
|
-
this.recordingEvents =
|
|
2857
|
-
this.recordingStartTime =
|
|
2854
|
+
const result = await response.json();
|
|
2855
|
+
if (result.success && result.data) {
|
|
2856
|
+
this.recordingEvents = result.data.events || [];
|
|
2857
|
+
this.recordingStartTime = result.data.startTime || this.recordingStartTime;
|
|
2858
2858
|
const recordingId = `rec_${this.recordingStartTime}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2859
2859
|
this.lastRecordingId = recordingId;
|
|
2860
2860
|
console.log(`[Haltija] Recording stopped (${this.recordingEvents.length} events)`);
|
|
@@ -3167,15 +3167,15 @@ class DevChannel extends HTMLElement {
|
|
|
3167
3167
|
headers: { "Content-Type": "application/json" },
|
|
3168
3168
|
body: JSON.stringify({ description, agentId })
|
|
3169
3169
|
});
|
|
3170
|
-
const
|
|
3171
|
-
if (
|
|
3170
|
+
const result = await response.json();
|
|
3171
|
+
if (result.error) {
|
|
3172
3172
|
if (successMsg) {
|
|
3173
|
-
successMsg.textContent = `⚠️ ${
|
|
3173
|
+
successMsg.textContent = `⚠️ ${result.error}`;
|
|
3174
3174
|
successMsg.style.color = "#f59e0b";
|
|
3175
3175
|
}
|
|
3176
3176
|
} else {
|
|
3177
3177
|
if (successMsg) {
|
|
3178
|
-
successMsg.textContent = `✓ Sent to ${agentName}${
|
|
3178
|
+
successMsg.textContent = `✓ Sent to ${agentName}${result.interrupted ? " (interrupted)" : ""}`;
|
|
3179
3179
|
successMsg.style.color = "#22c55e";
|
|
3180
3180
|
}
|
|
3181
3181
|
setTimeout(() => this.closeTestModal(), 1500);
|
|
@@ -3706,13 +3706,13 @@ class DevChannel extends HTMLElement {
|
|
|
3706
3706
|
const haltija = window.haltija;
|
|
3707
3707
|
if (haltija?.openAgentTab) {
|
|
3708
3708
|
newAgentText.textContent = "Creating...";
|
|
3709
|
-
const
|
|
3710
|
-
if (
|
|
3709
|
+
const result = await haltija.openAgentTab();
|
|
3710
|
+
if (result?.shellId) {
|
|
3711
3711
|
await new Promise((r) => setTimeout(r, 300));
|
|
3712
3712
|
if (type === "selection") {
|
|
3713
|
-
this.sendSelectionToAgent(
|
|
3713
|
+
this.sendSelectionToAgent(result.shellId, result.name || "agent");
|
|
3714
3714
|
} else if (type === "recording") {
|
|
3715
|
-
this.sendRecordingToAgent(
|
|
3715
|
+
this.sendRecordingToAgent(result.shellId, result.name || "agent");
|
|
3716
3716
|
}
|
|
3717
3717
|
} else {
|
|
3718
3718
|
console.error(`${LOG_PREFIX} Failed to create agent tab`);
|
|
@@ -3781,8 +3781,8 @@ ${elementSummary}${moreText}`;
|
|
|
3781
3781
|
context: `selection from ${window.location.host}`
|
|
3782
3782
|
})
|
|
3783
3783
|
});
|
|
3784
|
-
const
|
|
3785
|
-
if (
|
|
3784
|
+
const result = await response.json();
|
|
3785
|
+
if (result.sent) {
|
|
3786
3786
|
this.clearSelection();
|
|
3787
3787
|
console.log(`${LOG_PREFIX} Selection sent to ${agentName}`);
|
|
3788
3788
|
}
|
|
@@ -5297,11 +5297,11 @@ ${elementSummary}${moreText}`;
|
|
|
5297
5297
|
this.respond(msg2.id, false, undefined, "Video capture requires the Haltija Desktop app. Run: npx haltija@latest -f");
|
|
5298
5298
|
return;
|
|
5299
5299
|
}
|
|
5300
|
-
haltija.startVideoCapture({ maxDuration: payload2.maxDuration }).then((
|
|
5301
|
-
if (
|
|
5302
|
-
this.respond(msg2.id, true, { recordingId:
|
|
5300
|
+
haltija.startVideoCapture({ maxDuration: payload2.maxDuration }).then((result) => {
|
|
5301
|
+
if (result.success) {
|
|
5302
|
+
this.respond(msg2.id, true, { recordingId: result.recordingId });
|
|
5303
5303
|
} else {
|
|
5304
|
-
this.respond(msg2.id, false, undefined,
|
|
5304
|
+
this.respond(msg2.id, false, undefined, result.error || "Failed to start video");
|
|
5305
5305
|
}
|
|
5306
5306
|
}).catch((err) => {
|
|
5307
5307
|
this.respond(msg2.id, false, undefined, `Failed to start video: ${err.message}`);
|
|
@@ -5311,11 +5311,11 @@ ${elementSummary}${moreText}`;
|
|
|
5311
5311
|
this.respond(msg2.id, false, undefined, "Video capture requires the Haltija Desktop app. Run: npx haltija@latest -f");
|
|
5312
5312
|
return;
|
|
5313
5313
|
}
|
|
5314
|
-
haltija.stopVideoCapture().then((
|
|
5315
|
-
if (
|
|
5316
|
-
this.respond(msg2.id, true, { path:
|
|
5314
|
+
haltija.stopVideoCapture().then((result) => {
|
|
5315
|
+
if (result.success) {
|
|
5316
|
+
this.respond(msg2.id, true, { path: result.path, duration: result.duration, size: result.size, format: result.format });
|
|
5317
5317
|
} else {
|
|
5318
|
-
this.respond(msg2.id, false, undefined,
|
|
5318
|
+
this.respond(msg2.id, false, undefined, result.error || "Failed to stop video");
|
|
5319
5319
|
}
|
|
5320
5320
|
}).catch((err) => {
|
|
5321
5321
|
this.respond(msg2.id, false, undefined, `Failed to stop video: ${err.message}`);
|
|
@@ -5325,8 +5325,8 @@ ${elementSummary}${moreText}`;
|
|
|
5325
5325
|
this.respond(msg2.id, true, { recording: false });
|
|
5326
5326
|
return;
|
|
5327
5327
|
}
|
|
5328
|
-
haltija.videoStatus().then((
|
|
5329
|
-
this.respond(msg2.id, true,
|
|
5328
|
+
haltija.videoStatus().then((result) => {
|
|
5329
|
+
this.respond(msg2.id, true, result);
|
|
5330
5330
|
}).catch(() => {
|
|
5331
5331
|
this.respond(msg2.id, true, { recording: false });
|
|
5332
5332
|
});
|
|
@@ -5343,8 +5343,8 @@ ${elementSummary}${moreText}`;
|
|
|
5343
5343
|
this.respond(msg2.id, false, undefined, notAvailable);
|
|
5344
5344
|
return;
|
|
5345
5345
|
}
|
|
5346
|
-
haltija.networkWatch(payload2 || {}).then((
|
|
5347
|
-
this.respond(msg2.id,
|
|
5346
|
+
haltija.networkWatch(payload2 || {}).then((result) => {
|
|
5347
|
+
this.respond(msg2.id, result.success !== false, result);
|
|
5348
5348
|
}).catch((err) => {
|
|
5349
5349
|
this.respond(msg2.id, false, undefined, err.message);
|
|
5350
5350
|
});
|
|
@@ -5353,8 +5353,8 @@ ${elementSummary}${moreText}`;
|
|
|
5353
5353
|
this.respond(msg2.id, false, undefined, notAvailable);
|
|
5354
5354
|
return;
|
|
5355
5355
|
}
|
|
5356
|
-
haltija.networkUnwatch().then((
|
|
5357
|
-
this.respond(msg2.id, true,
|
|
5356
|
+
haltija.networkUnwatch().then((result) => {
|
|
5357
|
+
this.respond(msg2.id, true, result);
|
|
5358
5358
|
}).catch((err) => {
|
|
5359
5359
|
this.respond(msg2.id, false, undefined, err.message);
|
|
5360
5360
|
});
|
|
@@ -5363,8 +5363,8 @@ ${elementSummary}${moreText}`;
|
|
|
5363
5363
|
this.respond(msg2.id, false, undefined, notAvailable);
|
|
5364
5364
|
return;
|
|
5365
5365
|
}
|
|
5366
|
-
haltija.networkLog(payload2 || {}).then((
|
|
5367
|
-
this.respond(msg2.id, true,
|
|
5366
|
+
haltija.networkLog(payload2 || {}).then((result) => {
|
|
5367
|
+
this.respond(msg2.id, true, result);
|
|
5368
5368
|
}).catch((err) => {
|
|
5369
5369
|
this.respond(msg2.id, false, undefined, err.message);
|
|
5370
5370
|
});
|
|
@@ -5373,8 +5373,8 @@ ${elementSummary}${moreText}`;
|
|
|
5373
5373
|
this.respond(msg2.id, false, undefined, notAvailable);
|
|
5374
5374
|
return;
|
|
5375
5375
|
}
|
|
5376
|
-
haltija.networkStats().then((
|
|
5377
|
-
this.respond(msg2.id, true,
|
|
5376
|
+
haltija.networkStats().then((result) => {
|
|
5377
|
+
this.respond(msg2.id, true, result);
|
|
5378
5378
|
}).catch((err) => {
|
|
5379
5379
|
this.respond(msg2.id, false, undefined, err.message);
|
|
5380
5380
|
});
|
|
@@ -5383,8 +5383,8 @@ ${elementSummary}${moreText}`;
|
|
|
5383
5383
|
this.respond(msg2.id, false, undefined, notAvailable);
|
|
5384
5384
|
return;
|
|
5385
5385
|
}
|
|
5386
|
-
haltija.networkClear().then((
|
|
5387
|
-
this.respond(msg2.id, true,
|
|
5386
|
+
haltija.networkClear().then((result) => {
|
|
5387
|
+
this.respond(msg2.id, true, result);
|
|
5388
5388
|
}).catch((err) => {
|
|
5389
5389
|
this.respond(msg2.id, false, undefined, err.message);
|
|
5390
5390
|
});
|
|
@@ -5830,9 +5830,9 @@ ${elementSummary}${moreText}`;
|
|
|
5830
5830
|
try {
|
|
5831
5831
|
const capturePromise = targetSelector ? haltija.captureElement(targetSelector) : haltija.capturePage();
|
|
5832
5832
|
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve({ success: false, error: "Screenshot capture timed out after 10s" }), 1e4));
|
|
5833
|
-
const
|
|
5834
|
-
if (
|
|
5835
|
-
const converted = await convertFormat(
|
|
5833
|
+
const result = await Promise.race([capturePromise, timeoutPromise]);
|
|
5834
|
+
if (result?.success && result.data) {
|
|
5835
|
+
const converted = await convertFormat(result.data);
|
|
5836
5836
|
this.respond(msg2.id, true, {
|
|
5837
5837
|
image: converted.image,
|
|
5838
5838
|
viewport,
|
|
@@ -5842,8 +5842,8 @@ ${elementSummary}${moreText}`;
|
|
|
5842
5842
|
source: "electron"
|
|
5843
5843
|
});
|
|
5844
5844
|
return;
|
|
5845
|
-
} else if (
|
|
5846
|
-
this.respond(msg2.id, false, null,
|
|
5845
|
+
} else if (result && !result.success) {
|
|
5846
|
+
this.respond(msg2.id, false, null, result.error || "Electron capture failed");
|
|
5847
5847
|
return;
|
|
5848
5848
|
}
|
|
5849
5849
|
} catch (err) {
|
|
@@ -5914,14 +5914,29 @@ ${elementSummary}${moreText}`;
|
|
|
5914
5914
|
this.respond(msg2.id, true);
|
|
5915
5915
|
}
|
|
5916
5916
|
}
|
|
5917
|
-
async handleEvalMessage(
|
|
5917
|
+
async handleEvalMessage(msg2) {
|
|
5918
5918
|
try {
|
|
5919
|
-
const result =
|
|
5919
|
+
const result = this.evalCode(msg2.payload.code);
|
|
5920
5920
|
const resolved = result instanceof Promise ? await result : result;
|
|
5921
|
-
this.respond(
|
|
5921
|
+
this.respond(msg2.id, true, resolved);
|
|
5922
5922
|
} catch (err) {
|
|
5923
|
-
this.respond(
|
|
5923
|
+
this.respond(msg2.id, false, null, err.message);
|
|
5924
|
+
}
|
|
5925
|
+
}
|
|
5926
|
+
evalCode(code) {
|
|
5927
|
+
try {
|
|
5928
|
+
return eval(code);
|
|
5929
|
+
} catch (err) {
|
|
5930
|
+
if (!(err instanceof SyntaxError) || !/\b(await|return)\b/.test(code))
|
|
5931
|
+
throw err;
|
|
5932
|
+
}
|
|
5933
|
+
try {
|
|
5934
|
+
return eval(`(async () => (${code}))()`);
|
|
5935
|
+
} catch (err) {
|
|
5936
|
+
if (!(err instanceof SyntaxError))
|
|
5937
|
+
throw err;
|
|
5924
5938
|
}
|
|
5939
|
+
return eval(`(async () => { ${code} })()`);
|
|
5925
5940
|
}
|
|
5926
5941
|
async handleFetchMessage(msg2) {
|
|
5927
5942
|
const { url } = msg2.payload;
|
|
@@ -5999,14 +6014,14 @@ ${elementSummary}${moreText}`;
|
|
|
5999
6014
|
let el = null;
|
|
6000
6015
|
let targetDesc = "";
|
|
6001
6016
|
if (ref) {
|
|
6002
|
-
const
|
|
6003
|
-
el =
|
|
6017
|
+
const result = refRegistry.resolveWithStatus(ref);
|
|
6018
|
+
el = result.element;
|
|
6004
6019
|
targetDesc = `@${ref}`;
|
|
6005
6020
|
if (el) {
|
|
6006
6021
|
stats.refsResolved++;
|
|
6007
6022
|
} else {
|
|
6008
6023
|
stats.refsStale++;
|
|
6009
|
-
const errorMsg =
|
|
6024
|
+
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)`;
|
|
6010
6025
|
this.respond(responseId, false, null, errorMsg);
|
|
6011
6026
|
return;
|
|
6012
6027
|
}
|
|
@@ -6351,14 +6366,14 @@ ${elementSummary}${moreText}`;
|
|
|
6351
6366
|
let el = null;
|
|
6352
6367
|
let targetDesc = "";
|
|
6353
6368
|
if (payload2.ref) {
|
|
6354
|
-
const
|
|
6355
|
-
el =
|
|
6369
|
+
const result = refRegistry.resolveWithStatus(payload2.ref);
|
|
6370
|
+
el = result.element;
|
|
6356
6371
|
targetDesc = `@${payload2.ref}`;
|
|
6357
6372
|
if (el) {
|
|
6358
6373
|
stats.refsResolved++;
|
|
6359
6374
|
} else {
|
|
6360
6375
|
stats.refsStale++;
|
|
6361
|
-
const errorMsg =
|
|
6376
|
+
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)`;
|
|
6362
6377
|
this.respond(responseId, false, null, errorMsg);
|
|
6363
6378
|
return;
|
|
6364
6379
|
}
|
|
@@ -6427,15 +6442,15 @@ ${elementSummary}${moreText}`;
|
|
|
6427
6442
|
let target = null;
|
|
6428
6443
|
let targetDesc = "";
|
|
6429
6444
|
if (ref) {
|
|
6430
|
-
const
|
|
6431
|
-
target =
|
|
6445
|
+
const result = refRegistry.resolveWithStatus(ref);
|
|
6446
|
+
target = result.element;
|
|
6432
6447
|
targetDesc = `@${ref}`;
|
|
6433
6448
|
if (target) {
|
|
6434
6449
|
stats.refsResolved++;
|
|
6435
6450
|
target.focus();
|
|
6436
6451
|
} else {
|
|
6437
6452
|
stats.refsStale++;
|
|
6438
|
-
const errorMsg =
|
|
6453
|
+
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)`;
|
|
6439
6454
|
this.respond(responseId, false, null, errorMsg);
|
|
6440
6455
|
return;
|
|
6441
6456
|
}
|
|
@@ -6827,9 +6842,9 @@ ${elementSummary}${moreText}`;
|
|
|
6827
6842
|
});
|
|
6828
6843
|
} else if (action2 === "result") {
|
|
6829
6844
|
if (this.selectionResult) {
|
|
6830
|
-
const
|
|
6845
|
+
const result = this.selectionResult;
|
|
6831
6846
|
this.clearSelection();
|
|
6832
|
-
this.respond(msg2.id, true,
|
|
6847
|
+
this.respond(msg2.id, true, result);
|
|
6833
6848
|
} else {
|
|
6834
6849
|
this.respond(msg2.id, false, null, "No selection available");
|
|
6835
6850
|
}
|