local-operator-ui 0.41.1 → 0.41.2
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/out/main/index.js +390 -26
- package/out/preload/index.js +19 -0
- package/out/renderer/assets/{_basePickBy-BP7Q8i4W.js → _basePickBy-BgapP5T6.js} +1 -1
- package/out/renderer/assets/{_baseUniq-D36dAcoY.js → _baseUniq-B9rnfho3.js} +1 -1
- package/out/renderer/assets/{agent-details-page-D3ljlPdf.js → agent-details-page-CKRUVtjJ.js} +1 -1
- package/out/renderer/assets/{agent-hub-page-BMyIHnNM.js → agent-hub-page-5qLVOZEV.js} +1 -1
- package/out/renderer/assets/{agents-page-mMqgQd2V.js → agents-page-tQooOOKH.js} +3 -3
- package/out/renderer/assets/{arc-GVvow4so.js → arc-Feq-cl9G.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-BjGwXAtH.js → architectureDiagram-IEHRJDOE-BmZeJuzA.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-BTuigKlt.js → blockDiagram-JOT3LUYC-DEqkKuOE.js} +1 -1
- package/out/renderer/assets/{browser-page-B3mjDx8k.js → browser-page-CB-_usY1.js} +1 -1
- package/out/renderer/assets/{browser-webauthn-prompt-CzYoJfO4.js → browser-webauthn-prompt-CKUBOIHd.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-DK7eaKE8.js → c4Diagram-VJAJSXHY-EbhUbSdf.js} +1 -1
- package/out/renderer/assets/channel-CPGK3lub.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-DkQrsDhM.js → chunk-4BMEZGHF-DIk7XDrx.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-guh0INPR.js → chunk-A2AXSNBT-D_MflthZ.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-DvgIx6-r.js → chunk-AEK57VVT-C0iLgwbv.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-FNdvnFYo.js → chunk-D6G4REZN-BbFuFCzc.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-CgCQC9Mn.js → chunk-RZ5BOZE2-BxQo8VeZ.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-D1VRTTc4.js → chunk-XZIHB7SX-DnNtYGsR.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-hDc6ku-l.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-hDc6ku-l.js +1 -0
- package/out/renderer/assets/clone--PuuOIog.js +1 -0
- package/out/renderer/assets/{console-mirror-DRkz3vUY.js → console-mirror-Bxl6t4e9.js} +1 -1
- package/out/renderer/assets/{consoleCapture-BJfSUatx.js → consoleCapture-BzSftKjg.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-CJU5GIzR.js → conversation-input-sync-MZPvyAzc.js} +239 -239
- package/out/renderer/assets/{dagre-OKDRZEBW-DeeYQh6O.js → dagre-OKDRZEBW-qejdp-TF.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-DD-xNxKH.js → diagram-SSKATNLV-qHrLhzXc.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-YAoPlXaR.js → diagram-VNBRO52H-q0teJTmh.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-OKzGXyMI.js → erDiagram-Q7BY3M3F-DI6rp9FR.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-BG-3pPqS.js → flowDiagram-4HSFHLVR-xVi21DAI.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-CRyD5vsE.js → ganttDiagram-APWFNJXF-BUKGBOB_.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-aly2C__q.js → gitGraphDiagram-7IBYFJ6S-CdE3ZeMn.js} +1 -1
- package/out/renderer/assets/{graph-CCWwMmhg.js → graph-CRaHrZRK.js} +1 -1
- package/out/renderer/assets/{index-BaNzqqGN.js → index-B9E-fwX4.js} +1 -1
- package/out/renderer/assets/{index-CRjnV9wx.js → index-DknTGnAk.js} +208 -208
- package/out/renderer/assets/{index-DaCf2W9T.js → index-FsaxlHdZ.js} +1 -1
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-BY536sF5.js → infoDiagram-PH2N3AL5-pOK9P20l.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-DGvx__t6.js → journeyDiagram-U35MCT3I-D5Sg1JPA.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-CG2Lgkpw.js → kanban-definition-NDS4AKOZ-BfhWqBCl.js} +1 -1
- package/out/renderer/assets/{layout-vpRrwE7T.js → layout-IqsTm240.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-D6Yma1Gm.js → legacy-agents-page-bdH6oKjE.js} +5 -5
- package/out/renderer/assets/{library-page-B0gC-rRh.js → library-page-DDvrG_aA.js} +3 -3
- package/out/renderer/assets/{mermaid.core-COeGB8I0.js → mermaid.core-D0YPuNli.js} +5 -5
- package/out/renderer/assets/{mesh-page-PabU05tN.js → mesh-page-DYFNof_0.js} +1 -1
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-B0hkjZLY.js → mindmap-definition-ALO5MXBD-Tx5iMDRU.js} +1 -1
- package/out/renderer/assets/{mini-Df5C4rpd.js → mini-BoZCnSK9.js} +1 -1
- package/out/renderer/assets/{org-access-BacMtLkn.js → org-access-DoZK5gF3.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-tkB025lu.js → org-surface-gate-Dy0B7mtt.js} +1 -1
- package/out/renderer/assets/path-utils-CRYGE4mK.js +58 -0
- package/out/renderer/assets/{pieDiagram-IB7DONF6-DfFtQXU5.js → pieDiagram-IB7DONF6-D0rED3_3.js} +1 -1
- package/out/renderer/assets/{projects-page-CoHTKLZH.js → projects-page-D7j1GOvI.js} +1 -1
- package/out/renderer/assets/{publication-validation-B0Mf3mmP.js → publication-validation-CLbFS0n9.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-C4eDJWaK.js → quadrantDiagram-7GDLP6J5-D8jKSQt5.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-BEv1HS9Q.js → radar-MK3ICKWK-Co2EJbaJ.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-BX5vf982.js → radient-auth-buttons-B11cdRmS.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-B7f3qUcB.js → requirementDiagram-KVF5MWMF-BI13h11j.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-xM7E-74l.js → sankeyDiagram-QLVOVGJD-D4hZ6_ML.js} +1 -1
- package/out/renderer/assets/{schedules-page-5q7pvL1H.js → schedules-page-DFfDDHYC.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-upwR02kU.js → sequenceDiagram-X6HHIX6F-U6CqBtco.js} +1 -1
- package/out/renderer/assets/{settings-page-DcnGr-GP.js → settings-page-CZ7NUDoe.js} +9 -9
- package/out/renderer/assets/{smartart-CYnMNs5u.js → smartart-BVm_cEaq.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-BqTri7Q-.js → stateDiagram-DGXRK772-DBg11bkx.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-jmaink9i.js +1 -0
- package/out/renderer/assets/team-bridge-page-u_OqiZGS.js +16 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-Bi2is17s.js → timeline-definition-BDJGKUSR-WQ6aYia6.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-PHtokPlg.js → use-download-agent-mutation-ZoivWizY.js} +2 -2
- package/out/renderer/assets/{use-session-snapshot-B5sxthdQ.js → use-session-snapshot-CdYiirKJ.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-B0TrjzLJ.js → xychartDiagram-VJFVF3MP-f11BpHer.js} +1 -1
- package/out/renderer/console-capture.html +3 -3
- package/out/renderer/index.html +4 -4
- package/out/renderer/mini.html +4 -4
- package/package.json +4 -3
- package/out/renderer/assets/channel-B05rL6In.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-DpB8-8cT.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-DpB8-8cT.js +0 -1
- package/out/renderer/assets/clone-BHHjv3HP.js +0 -1
- package/out/renderer/assets/path-utils-Ct0VTUZS.js +0 -58
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-D8Sl1QhX.js +0 -1
- package/out/renderer/assets/team-bridge-page-vnNJdCi3.js +0 -16
package/out/main/index.js
CHANGED
|
@@ -2423,6 +2423,7 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2423
2423
|
}).strict(),
|
|
2424
2424
|
zod.z.object({
|
|
2425
2425
|
op: zod.z.literal("team_bridge.conversations.create"),
|
|
2426
|
+
expected_account_id: id$1.optional(),
|
|
2426
2427
|
tenant_id: id$1.optional(),
|
|
2427
2428
|
kind: zod.z.enum(["dm", "group", "channel"]),
|
|
2428
2429
|
name: zod.z.string().min(1).max(128).optional(),
|
|
@@ -2440,6 +2441,8 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2440
2441
|
}).strict(),
|
|
2441
2442
|
zod.z.object({
|
|
2442
2443
|
op: zod.z.literal("team_bridge.conversations.lifecycle"),
|
|
2444
|
+
expected_account_id: id$1.optional(),
|
|
2445
|
+
tenant_id: id$1.optional(),
|
|
2443
2446
|
conversation_id: id$1,
|
|
2444
2447
|
action: zod.z.enum(["archive", "unarchive", "join", "leave"])
|
|
2445
2448
|
}).strict(),
|
|
@@ -2456,17 +2459,20 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2456
2459
|
*/
|
|
2457
2460
|
zod.z.object({
|
|
2458
2461
|
op: zod.z.literal("team_bridge.conversations.join"),
|
|
2462
|
+
expected_account_id: id$1.optional(),
|
|
2459
2463
|
conversation_id: id$1,
|
|
2460
2464
|
tenant_id: id$1.optional()
|
|
2461
2465
|
}).strict(),
|
|
2462
2466
|
zod.z.object({
|
|
2463
2467
|
op: zod.z.literal("team_bridge.conversations.notify"),
|
|
2468
|
+
expected_account_id: id$1.optional(),
|
|
2464
2469
|
conversation_id: id$1,
|
|
2465
2470
|
tenant_id: id$1.optional(),
|
|
2466
2471
|
notify: zod.z.enum(["all", "mention", "mute"])
|
|
2467
2472
|
}).strict(),
|
|
2468
2473
|
zod.z.object({
|
|
2469
2474
|
op: zod.z.literal("team_bridge.conversations.members.add"),
|
|
2475
|
+
expected_account_id: id$1.optional(),
|
|
2470
2476
|
conversation_id: id$1,
|
|
2471
2477
|
tenant_id: id$1.optional(),
|
|
2472
2478
|
members: zod.z.array(
|
|
@@ -2480,11 +2486,14 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2480
2486
|
}).strict(),
|
|
2481
2487
|
zod.z.object({
|
|
2482
2488
|
op: zod.z.literal("team_bridge.conversations.members.remove"),
|
|
2489
|
+
expected_account_id: id$1.optional(),
|
|
2490
|
+
tenant_id: id$1.optional(),
|
|
2483
2491
|
conversation_id: id$1,
|
|
2484
2492
|
account_id: id$1
|
|
2485
2493
|
}).strict(),
|
|
2486
2494
|
zod.z.object({
|
|
2487
2495
|
op: zod.z.literal("team_bridge.conversations.consent"),
|
|
2496
|
+
expected_account_id: id$1.optional(),
|
|
2488
2497
|
conversation_id: id$1,
|
|
2489
2498
|
account_id: id$1,
|
|
2490
2499
|
decision: zod.z.enum(["accept", "decline"]),
|
|
@@ -2509,6 +2518,7 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2509
2518
|
}).strict(),
|
|
2510
2519
|
zod.z.object({
|
|
2511
2520
|
op: zod.z.literal("team_bridge.messages.send"),
|
|
2521
|
+
expected_account_id: id$1.optional(),
|
|
2512
2522
|
conversation_id: id$1,
|
|
2513
2523
|
tenant_id: id$1.optional(),
|
|
2514
2524
|
client_ref: id$1,
|
|
@@ -2531,6 +2541,7 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2531
2541
|
}).strict(),
|
|
2532
2542
|
zod.z.object({
|
|
2533
2543
|
op: zod.z.literal("team_bridge.read"),
|
|
2544
|
+
expected_account_id: id$1.optional(),
|
|
2534
2545
|
conversation_id: id$1,
|
|
2535
2546
|
tenant_id: id$1.optional(),
|
|
2536
2547
|
seq: zod.z.number().int().nonnegative().optional(),
|
|
@@ -3058,6 +3069,14 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
3058
3069
|
]);
|
|
3059
3070
|
const desktopRequestSchema = desktopRequestUnion.superRefine(
|
|
3060
3071
|
(request, ctx) => {
|
|
3072
|
+
if (request.op.startsWith("team_bridge.") && "expected_account_id" in request && request.expected_account_id && (!("tenant_id" in request) || !request.tenant_id)) {
|
|
3073
|
+
ctx.addIssue({
|
|
3074
|
+
code: zod.z.ZodIssueCode.custom,
|
|
3075
|
+
path: ["tenant_id"],
|
|
3076
|
+
message: "Guarded conversation writes require an explicit tenant"
|
|
3077
|
+
});
|
|
3078
|
+
return;
|
|
3079
|
+
}
|
|
3061
3080
|
if (request.op === "hub.skillPull" || request.op === "hub.skillSubscribe" || request.op === "hub.skillPublish") {
|
|
3062
3081
|
if (request.visibility === "public" && request.tenantId !== null || request.visibility === "org" && !request.tenantId) {
|
|
3063
3082
|
ctx.addIssue({
|
|
@@ -3631,6 +3650,13 @@ function harnessImportBody(request) {
|
|
|
3631
3650
|
...request.maxSessions === void 0 ? {} : { max_sessions: request.maxSessions }
|
|
3632
3651
|
};
|
|
3633
3652
|
}
|
|
3653
|
+
function conversationOwnerQuery(request) {
|
|
3654
|
+
const query = new URLSearchParams();
|
|
3655
|
+
if (request.tenant_id) query.set("tenant_id", request.tenant_id);
|
|
3656
|
+
if (request.expected_account_id)
|
|
3657
|
+
query.set("expected_account_id", request.expected_account_id);
|
|
3658
|
+
return query.size ? `?${query.toString()}` : "";
|
|
3659
|
+
}
|
|
3634
3660
|
function tenantQuery(tenantId) {
|
|
3635
3661
|
return tenantId === void 0 ? "" : `?tenant_id=${encodeURIComponent(tenantId)}`;
|
|
3636
3662
|
}
|
|
@@ -5026,6 +5052,7 @@ function desktopEndpoint(request) {
|
|
|
5026
5052
|
path: "/v1/desktop/team-bridge/conversations",
|
|
5027
5053
|
method: "POST",
|
|
5028
5054
|
body: {
|
|
5055
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {},
|
|
5029
5056
|
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5030
5057
|
kind: request.kind,
|
|
5031
5058
|
...request.name ? { name: request.name } : {},
|
|
@@ -5037,14 +5064,25 @@ function desktopEndpoint(request) {
|
|
|
5037
5064
|
};
|
|
5038
5065
|
case "team_bridge.conversations.lifecycle":
|
|
5039
5066
|
return {
|
|
5040
|
-
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/${request.action}`,
|
|
5041
|
-
method: "POST"
|
|
5067
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/${request.action}${request.action === "join" ? "" : conversationOwnerQuery(request)}`,
|
|
5068
|
+
method: "POST",
|
|
5069
|
+
...request.action === "join" && (request.tenant_id || request.expected_account_id) ? {
|
|
5070
|
+
body: {
|
|
5071
|
+
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5072
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {}
|
|
5073
|
+
}
|
|
5074
|
+
} : {}
|
|
5042
5075
|
};
|
|
5043
5076
|
case "team_bridge.conversations.join":
|
|
5044
5077
|
return {
|
|
5045
5078
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/join`,
|
|
5046
5079
|
method: "POST",
|
|
5047
|
-
...request.tenant_id
|
|
5080
|
+
...request.tenant_id || request.expected_account_id ? {
|
|
5081
|
+
body: {
|
|
5082
|
+
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5083
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {}
|
|
5084
|
+
}
|
|
5085
|
+
} : {}
|
|
5048
5086
|
};
|
|
5049
5087
|
case "team_bridge.conversations.notify":
|
|
5050
5088
|
return {
|
|
@@ -5053,6 +5091,7 @@ function desktopEndpoint(request) {
|
|
|
5053
5091
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/read`,
|
|
5054
5092
|
method: "POST",
|
|
5055
5093
|
body: {
|
|
5094
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {},
|
|
5056
5095
|
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5057
5096
|
notify: request.notify
|
|
5058
5097
|
}
|
|
@@ -5060,6 +5099,8 @@ function desktopEndpoint(request) {
|
|
|
5060
5099
|
case "team_bridge.conversations.members.add": {
|
|
5061
5100
|
const query = new URLSearchParams();
|
|
5062
5101
|
if (request.tenant_id) query.set("tenant_id", request.tenant_id);
|
|
5102
|
+
if (request.expected_account_id)
|
|
5103
|
+
query.set("expected_account_id", request.expected_account_id);
|
|
5063
5104
|
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
5064
5105
|
return {
|
|
5065
5106
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/members${suffix}`,
|
|
@@ -5069,7 +5110,7 @@ function desktopEndpoint(request) {
|
|
|
5069
5110
|
}
|
|
5070
5111
|
case "team_bridge.conversations.members.remove":
|
|
5071
5112
|
return {
|
|
5072
|
-
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/members/${encodeURIComponent(request.account_id)}`,
|
|
5113
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/members/${encodeURIComponent(request.account_id)}${conversationOwnerQuery(request)}`,
|
|
5073
5114
|
method: "DELETE"
|
|
5074
5115
|
};
|
|
5075
5116
|
case "team_bridge.conversations.consent":
|
|
@@ -5077,6 +5118,7 @@ function desktopEndpoint(request) {
|
|
|
5077
5118
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/members/${encodeURIComponent(request.account_id)}/consent`,
|
|
5078
5119
|
method: "POST",
|
|
5079
5120
|
body: {
|
|
5121
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {},
|
|
5080
5122
|
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5081
5123
|
decision: request.decision,
|
|
5082
5124
|
consent_version: request.consent_version
|
|
@@ -5112,6 +5154,7 @@ function desktopEndpoint(request) {
|
|
|
5112
5154
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/messages`,
|
|
5113
5155
|
method: "POST",
|
|
5114
5156
|
body: {
|
|
5157
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {},
|
|
5115
5158
|
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5116
5159
|
client_ref: request.client_ref,
|
|
5117
5160
|
body: request.body,
|
|
@@ -5137,6 +5180,7 @@ function desktopEndpoint(request) {
|
|
|
5137
5180
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/read`,
|
|
5138
5181
|
method: "POST",
|
|
5139
5182
|
body: {
|
|
5183
|
+
...request.expected_account_id ? { expected_account_id: request.expected_account_id } : {},
|
|
5140
5184
|
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
5141
5185
|
...request.seq === void 0 ? {} : { seq: request.seq },
|
|
5142
5186
|
...request.muted === void 0 ? {} : { muted: request.muted }
|
|
@@ -64806,6 +64850,158 @@ function pageOf(view) {
|
|
|
64806
64850
|
title: view.webContents.isDestroyed() ? "" : view.webContents.getTitle()
|
|
64807
64851
|
};
|
|
64808
64852
|
}
|
|
64853
|
+
const LABELLABLE = /* @__PURE__ */ new Set([
|
|
64854
|
+
"checkbox",
|
|
64855
|
+
"radio",
|
|
64856
|
+
"switch",
|
|
64857
|
+
"textbox",
|
|
64858
|
+
"searchbox",
|
|
64859
|
+
"combobox",
|
|
64860
|
+
"listbox",
|
|
64861
|
+
"spinbutton",
|
|
64862
|
+
"slider",
|
|
64863
|
+
"button"
|
|
64864
|
+
]);
|
|
64865
|
+
const CLICKABLE = /* @__PURE__ */ new Set([
|
|
64866
|
+
"button",
|
|
64867
|
+
"link",
|
|
64868
|
+
"menuitem",
|
|
64869
|
+
"menuitemcheckbox",
|
|
64870
|
+
"menuitemradio",
|
|
64871
|
+
"tab",
|
|
64872
|
+
"option",
|
|
64873
|
+
"treeitem",
|
|
64874
|
+
"DisclosureTriangle",
|
|
64875
|
+
"checkbox",
|
|
64876
|
+
"radio",
|
|
64877
|
+
"switch"
|
|
64878
|
+
]);
|
|
64879
|
+
function normalise(value) {
|
|
64880
|
+
return String(value ?? "").replace(/\s+/g, " ").trim();
|
|
64881
|
+
}
|
|
64882
|
+
function readValue(raw) {
|
|
64883
|
+
const text = raw.trim();
|
|
64884
|
+
if (!text) return null;
|
|
64885
|
+
const quote = text[0];
|
|
64886
|
+
if (quote === '"' || quote === "'") {
|
|
64887
|
+
let value = "";
|
|
64888
|
+
for (let index = 1; index < text.length; index += 1) {
|
|
64889
|
+
const char = text[index] ?? "";
|
|
64890
|
+
if (char === "\\" && index + 1 < text.length) {
|
|
64891
|
+
value += text[index + 1] ?? "";
|
|
64892
|
+
index += 1;
|
|
64893
|
+
continue;
|
|
64894
|
+
}
|
|
64895
|
+
if (char === quote) {
|
|
64896
|
+
return index === text.length - 1 ? value : null;
|
|
64897
|
+
}
|
|
64898
|
+
value += char;
|
|
64899
|
+
}
|
|
64900
|
+
return null;
|
|
64901
|
+
}
|
|
64902
|
+
if (/[\[\]]/.test(text) || text.startsWith("*")) return null;
|
|
64903
|
+
return text;
|
|
64904
|
+
}
|
|
64905
|
+
function parseLocator(value) {
|
|
64906
|
+
const text = value.trim();
|
|
64907
|
+
const match = /^(role|label|text)(\*?)=([\s\S]+)$/i.exec(text);
|
|
64908
|
+
if (!match) return null;
|
|
64909
|
+
const kind = (match[1] ?? "").toLowerCase();
|
|
64910
|
+
const prefixSubstring = match[2] === "*";
|
|
64911
|
+
const rest = (match[3] ?? "").trim();
|
|
64912
|
+
if (kind === "role") {
|
|
64913
|
+
const roleMatch = /^([A-Za-z][A-Za-z0-9_-]*)\s*(?:\[\s*name(\*?)=\s*([\s\S]+?)\s*\])?$/.exec(rest);
|
|
64914
|
+
if (!roleMatch) return null;
|
|
64915
|
+
const role = roleMatch[1] ?? "";
|
|
64916
|
+
const substring = roleMatch[2] === "*";
|
|
64917
|
+
const rawName = roleMatch[3];
|
|
64918
|
+
const name2 = rawName === void 0 ? "" : readValue(rawName);
|
|
64919
|
+
if (name2 === null) return null;
|
|
64920
|
+
return { kind: "role", role: role.toLowerCase(), name: name2, substring };
|
|
64921
|
+
}
|
|
64922
|
+
const name = readValue(rest);
|
|
64923
|
+
if (name === null) return null;
|
|
64924
|
+
return { kind: kind === "label" ? "label" : "text", name, substring: prefixSubstring };
|
|
64925
|
+
}
|
|
64926
|
+
function matches(haystack, needle, substring) {
|
|
64927
|
+
const left = normalise(haystack).toLowerCase();
|
|
64928
|
+
const right = normalise(needle).toLowerCase();
|
|
64929
|
+
if (!right) return false;
|
|
64930
|
+
return substring ? left.includes(right) : left === right;
|
|
64931
|
+
}
|
|
64932
|
+
function candidateNodes(nodes) {
|
|
64933
|
+
return nodes.filter((node) => !node.ignored && node.backendDOMNodeId !== void 0);
|
|
64934
|
+
}
|
|
64935
|
+
function resolveLocator(nodes, locator) {
|
|
64936
|
+
const pool = candidateNodes(nodes);
|
|
64937
|
+
const hits = [];
|
|
64938
|
+
const consider = (role, name) => {
|
|
64939
|
+
if (locator.kind === "role") {
|
|
64940
|
+
if (role.toLowerCase() !== locator.role) return false;
|
|
64941
|
+
if (locator.name && !matches(name, locator.name, locator.substring)) return false;
|
|
64942
|
+
return true;
|
|
64943
|
+
}
|
|
64944
|
+
return matches(name, locator.name, locator.substring);
|
|
64945
|
+
};
|
|
64946
|
+
const collect = (accept) => {
|
|
64947
|
+
for (const node of pool) {
|
|
64948
|
+
const role = String(node.role?.value ?? "");
|
|
64949
|
+
const name = normalise(node.name?.value);
|
|
64950
|
+
if (!accept(role)) continue;
|
|
64951
|
+
if (!consider(role, name)) continue;
|
|
64952
|
+
hits.push({ backendNodeId: node.backendDOMNodeId, role, name, matched: 0 });
|
|
64953
|
+
}
|
|
64954
|
+
};
|
|
64955
|
+
if (locator.kind === "role") {
|
|
64956
|
+
collect(() => true);
|
|
64957
|
+
} else if (locator.kind === "label") {
|
|
64958
|
+
collect((role) => LABELLABLE.has(role));
|
|
64959
|
+
if (!hits.length) collect((role) => CLICKABLE.has(role));
|
|
64960
|
+
} else {
|
|
64961
|
+
collect((role) => CLICKABLE.has(role));
|
|
64962
|
+
if (!hits.length) collect(() => true);
|
|
64963
|
+
}
|
|
64964
|
+
const first = hits[0];
|
|
64965
|
+
if (!first) return null;
|
|
64966
|
+
return { ...first, matched: hits.length };
|
|
64967
|
+
}
|
|
64968
|
+
function locatorSuggestions(nodes, query, limit = 5) {
|
|
64969
|
+
const wanted = normalise(query).toLowerCase();
|
|
64970
|
+
const parsed = parseLocator(query);
|
|
64971
|
+
const term = parsed ? parsed.name.toLowerCase() : wanted;
|
|
64972
|
+
const words = term.split(/[^a-z0-9]+/).filter((word) => word.length > 1);
|
|
64973
|
+
const wantedRole = parsed && parsed.kind === "role" ? parsed.role : "";
|
|
64974
|
+
const scored = [];
|
|
64975
|
+
for (const node of candidateNodes(nodes)) {
|
|
64976
|
+
const role = String(node.role?.value ?? "");
|
|
64977
|
+
const name = normalise(node.name?.value);
|
|
64978
|
+
if (!name) continue;
|
|
64979
|
+
const lowerName = name.toLowerCase();
|
|
64980
|
+
let score = 0;
|
|
64981
|
+
if (term && lowerName === term) score += 100;
|
|
64982
|
+
else if (term && lowerName.includes(term)) score += 60;
|
|
64983
|
+
for (const word of words) if (lowerName.includes(word)) score += 8;
|
|
64984
|
+
if (wantedRole && role.toLowerCase() === wantedRole) score += 25;
|
|
64985
|
+
if (CLICKABLE.has(role)) score += 4;
|
|
64986
|
+
if (!score) continue;
|
|
64987
|
+
scored.push({ score, role, name });
|
|
64988
|
+
}
|
|
64989
|
+
scored.sort((left, right) => right.score - left.score || left.name.localeCompare(right.name));
|
|
64990
|
+
const seen = /* @__PURE__ */ new Set();
|
|
64991
|
+
const out = [];
|
|
64992
|
+
for (const entry of scored) {
|
|
64993
|
+
const key = `${entry.role}\0${entry.name}`;
|
|
64994
|
+
if (seen.has(key)) continue;
|
|
64995
|
+
seen.add(key);
|
|
64996
|
+
out.push({ role: entry.role, name: entry.name, locator: locatorFor(entry.role, entry.name) });
|
|
64997
|
+
if (out.length >= limit) break;
|
|
64998
|
+
}
|
|
64999
|
+
return out;
|
|
65000
|
+
}
|
|
65001
|
+
function locatorFor(role, name) {
|
|
65002
|
+
const quoted = name.includes('"') && !name.includes("'") ? `'${name.replace(/\\/g, "\\\\")}'` : JSON.stringify(name);
|
|
65003
|
+
return role && /^[A-Za-z][A-Za-z0-9_-]*$/.test(role) ? `role=${role}[name=${quoted}]` : `text=${quoted}`;
|
|
65004
|
+
}
|
|
64809
65005
|
const FRAME_HOP = ">>>";
|
|
64810
65006
|
const MAX_FRAME_DEPTH = 3;
|
|
64811
65007
|
const MAX_FRAMES_SEARCHED = 20;
|
|
@@ -65056,7 +65252,7 @@ async function resolveHops(ctx, contents, hops) {
|
|
|
65056
65252
|
return { scope, nodeId };
|
|
65057
65253
|
}
|
|
65058
65254
|
async function searchFrames(ctx, contents, selector) {
|
|
65059
|
-
const
|
|
65255
|
+
const matches2 = [];
|
|
65060
65256
|
const walk = await listFrames(ctx, contents);
|
|
65061
65257
|
for (const scope of walk.frames) {
|
|
65062
65258
|
const nodeId = await queryIn(ctx, contents, scope, selector).catch(
|
|
@@ -65065,9 +65261,9 @@ async function searchFrames(ctx, contents, selector) {
|
|
|
65065
65261
|
return 0;
|
|
65066
65262
|
}
|
|
65067
65263
|
);
|
|
65068
|
-
if (nodeId)
|
|
65264
|
+
if (nodeId) matches2.push({ scope, nodeId });
|
|
65069
65265
|
}
|
|
65070
|
-
return { matches, walk };
|
|
65266
|
+
return { matches: matches2, walk };
|
|
65071
65267
|
}
|
|
65072
65268
|
async function listFrames(ctx, contents) {
|
|
65073
65269
|
const walk = {
|
|
@@ -65202,24 +65398,46 @@ async function editableInFrame(ctx, contents, scope, target2) {
|
|
|
65202
65398
|
}
|
|
65203
65399
|
const LANDMARKS = /* @__PURE__ */ new Set(["banner", "main", "navigation", "complementary", "contentinfo", "form", "region"]);
|
|
65204
65400
|
const INTERACTIVE = /* @__PURE__ */ new Set(["button", "link", "textbox", "checkbox", "radio", "combobox", "menuitem", "tab", "switch", "slider", "spinbutton"]);
|
|
65205
|
-
function
|
|
65401
|
+
function stateSuffix(node) {
|
|
65402
|
+
const truthy = (value) => value === true || value === "true";
|
|
65403
|
+
const falsy = (value) => value === false || value === "false";
|
|
65404
|
+
const property = (name) => node.properties?.find((entry) => entry.name === name)?.value.value;
|
|
65405
|
+
const markers = [];
|
|
65406
|
+
if (falsy(property("expanded"))) markers.push("collapsed");
|
|
65407
|
+
const checked = property("checked");
|
|
65408
|
+
if (truthy(checked)) markers.push("checked");
|
|
65409
|
+
else if (checked === "mixed") markers.push("mixed");
|
|
65410
|
+
if (truthy(property("disabled"))) markers.push("disabled");
|
|
65411
|
+
return markers.length ? ` [${markers.join("] [")}]` : "";
|
|
65412
|
+
}
|
|
65413
|
+
function compactAX(nodes, epoch, options = {}) {
|
|
65206
65414
|
const byId = new Map(nodes.map((node) => [node.nodeId, node]));
|
|
65207
65415
|
const refs = {};
|
|
65208
65416
|
const lines = [];
|
|
65209
65417
|
let sequence = 0;
|
|
65418
|
+
const scopeId = options.rootBackendNodeId;
|
|
65419
|
+
let scopeAt = null;
|
|
65420
|
+
let framesInScope = 0;
|
|
65210
65421
|
const visited = /* @__PURE__ */ new Set();
|
|
65211
65422
|
function visit2(node, depth) {
|
|
65212
65423
|
if (visited.has(node.nodeId)) return;
|
|
65213
65424
|
visited.add(node.nodeId);
|
|
65425
|
+
const savedScope = scopeAt;
|
|
65426
|
+
if (scopeAt === null && scopeId !== void 0 && node.backendDOMNodeId === scopeId) {
|
|
65427
|
+
scopeAt = depth;
|
|
65428
|
+
}
|
|
65429
|
+
const inside2 = scopeId === void 0 || scopeAt !== null && depth >= scopeAt;
|
|
65214
65430
|
if (node.ignored) {
|
|
65215
65431
|
for (const child of node.childIds ?? []) {
|
|
65216
65432
|
const found = byId.get(child);
|
|
65217
65433
|
if (found) visit2(found, depth);
|
|
65218
65434
|
}
|
|
65435
|
+
scopeAt = savedScope;
|
|
65219
65436
|
return;
|
|
65220
65437
|
}
|
|
65221
65438
|
const role = String(node.role?.value ?? "");
|
|
65222
65439
|
const name = String(node.name?.value ?? "").trim();
|
|
65440
|
+
if (inside2 && role === "Iframe") framesInScope += 1;
|
|
65223
65441
|
const focusable = node.properties?.some((property) => property.name === "focusable" && property.value.value === true);
|
|
65224
65442
|
const interesting = INTERACTIVE.has(role) || LANDMARKS.has(role) || focusable || Boolean(name && role !== "StaticText");
|
|
65225
65443
|
if (interesting) {
|
|
@@ -65228,16 +65446,54 @@ function compactAX(nodes, epoch) {
|
|
|
65228
65446
|
ref = `e${++sequence}`;
|
|
65229
65447
|
refs[ref] = { backendNodeId: node.backendDOMNodeId, epoch };
|
|
65230
65448
|
}
|
|
65231
|
-
|
|
65449
|
+
if (inside2) {
|
|
65450
|
+
const shown = depth - (scopeAt ?? 0);
|
|
65451
|
+
lines.push(`${" ".repeat(shown)}- ${role || "node"}${name ? ` ${JSON.stringify(name)}` : ""}${ref ? ` [${ref}]` : ""}${stateSuffix(node)}`);
|
|
65452
|
+
}
|
|
65232
65453
|
}
|
|
65233
65454
|
for (const child of node.childIds ?? []) {
|
|
65234
65455
|
const found = byId.get(child);
|
|
65235
65456
|
if (found) visit2(found, interesting ? depth + 1 : depth);
|
|
65236
65457
|
}
|
|
65458
|
+
scopeAt = savedScope;
|
|
65459
|
+
}
|
|
65460
|
+
const scopedRoot = scopeId === void 0 ? void 0 : nodes.find((node) => node.backendDOMNodeId === scopeId);
|
|
65461
|
+
if (scopeId !== void 0 && scopedRoot === void 0) {
|
|
65462
|
+
return { snapshot: "", refs, framesInScope: 0, totalLines: 0, scoped: false };
|
|
65237
65463
|
}
|
|
65238
65464
|
const childIds = new Set(nodes.flatMap((node) => node.childIds ?? []));
|
|
65239
65465
|
for (const root of nodes.filter((node) => !childIds.has(node.nodeId))) visit2(root, 0);
|
|
65240
|
-
return {
|
|
65466
|
+
return {
|
|
65467
|
+
snapshot: lines.join("\n"),
|
|
65468
|
+
refs,
|
|
65469
|
+
// Unscoped means "the whole page", and every frame is then read by the
|
|
65470
|
+
// caller's own frame walk: the count exists only to explain a SCOPE.
|
|
65471
|
+
framesInScope: scopeId === void 0 ? 0 : framesInScope,
|
|
65472
|
+
totalLines: lines.length,
|
|
65473
|
+
scoped: scopeId !== void 0
|
|
65474
|
+
};
|
|
65475
|
+
}
|
|
65476
|
+
function windowSnapshot(text, options = {}) {
|
|
65477
|
+
const lines = text ? text.split("\n").filter((line) => line.length > 0) : [];
|
|
65478
|
+
const totalLines = lines.length;
|
|
65479
|
+
const search = String(options.search ?? "").trim();
|
|
65480
|
+
const matched = search ? lines.filter((line) => line.toLowerCase().includes(search.toLowerCase())) : lines;
|
|
65481
|
+
const matchedLines = matched.length;
|
|
65482
|
+
const requested = Number(options.start ?? 1);
|
|
65483
|
+
const start = Number.isFinite(requested) && requested >= 1 ? Math.floor(requested) : 1;
|
|
65484
|
+
const rawLimit = Number(options.limit ?? 0);
|
|
65485
|
+
const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.floor(rawLimit) : 0;
|
|
65486
|
+
const end = limit ? start - 1 + limit : matchedLines;
|
|
65487
|
+
const page = matched.slice(start - 1, end);
|
|
65488
|
+
return {
|
|
65489
|
+
text: page.join("\n"),
|
|
65490
|
+
totalLines,
|
|
65491
|
+
matchedLines,
|
|
65492
|
+
returnedLines: page.length,
|
|
65493
|
+
start,
|
|
65494
|
+
limit,
|
|
65495
|
+
search
|
|
65496
|
+
};
|
|
65241
65497
|
}
|
|
65242
65498
|
const PAGE_OVERLAP_PX = 80;
|
|
65243
65499
|
function defaultScrollExpression() {
|
|
@@ -65317,6 +65573,8 @@ async function read(ctx, params) {
|
|
|
65317
65573
|
async function snapshot(ctx, params) {
|
|
65318
65574
|
const record = ctx.registry.requireSurface(params.tab);
|
|
65319
65575
|
const contents = record.view.webContents;
|
|
65576
|
+
const scope = stringParam(params, "selector");
|
|
65577
|
+
const rootBackendNodeId = scope ? await backendNodeIdForSelector(ctx, record.view, scope) : void 0;
|
|
65320
65578
|
await ctx.cdp.send(contents, "Accessibility.enable", {});
|
|
65321
65579
|
let nodes = [];
|
|
65322
65580
|
try {
|
|
@@ -65330,22 +65588,49 @@ async function snapshot(ctx, params) {
|
|
|
65330
65588
|
await ctx.cdp.send(contents, "Accessibility.disable", {}).catch(() => {
|
|
65331
65589
|
});
|
|
65332
65590
|
}
|
|
65333
|
-
const {
|
|
65334
|
-
|
|
65335
|
-
|
|
65336
|
-
|
|
65591
|
+
const {
|
|
65592
|
+
snapshot: topRendered,
|
|
65593
|
+
refs: topRefs,
|
|
65594
|
+
scoped,
|
|
65595
|
+
framesInScope
|
|
65596
|
+
} = compactAX(nodes, record.epoch, { rootBackendNodeId });
|
|
65597
|
+
if (rootBackendNodeId !== void 0 && !scoped) {
|
|
65598
|
+
throw new BridgeCommandError(
|
|
65599
|
+
"element_not_found",
|
|
65600
|
+
`selector ${scope} matched an element with no accessibility subtree (hidden, aria-hidden, or inside a collapsed section); expand it first, then snapshot again`
|
|
65601
|
+
);
|
|
65602
|
+
}
|
|
65337
65603
|
const refs = { ...topRefs };
|
|
65338
65604
|
let rendered = topRendered;
|
|
65339
|
-
if (nodes.some(isFrameNode)) {
|
|
65605
|
+
if (!scope && nodes.some(isFrameNode)) {
|
|
65340
65606
|
const blocks = await frameSnapshots(ctx, record, nodes, refs);
|
|
65341
65607
|
if (blocks.length) rendered = [rendered, ...blocks].join("\n");
|
|
65342
65608
|
}
|
|
65343
65609
|
record.refs = refs;
|
|
65344
65610
|
ctx.registry.touch(record);
|
|
65611
|
+
let note = "";
|
|
65612
|
+
if (scope && framesInScope > 0) {
|
|
65613
|
+
const frames = framesInScope;
|
|
65614
|
+
note = `
|
|
65615
|
+
- (a scoped snapshot does not read frames: this section contains ${frames} frame${frames === 1 ? "" : "s"}; snapshot without selector= for their contents)`;
|
|
65616
|
+
}
|
|
65617
|
+
const page = windowSnapshot(rendered, {
|
|
65618
|
+
search: stringParam(params, "search"),
|
|
65619
|
+
start: numberParam(params, "start") ?? 1,
|
|
65620
|
+
limit: numberParam(params, "limit") ?? 0
|
|
65621
|
+
});
|
|
65345
65622
|
return {
|
|
65346
|
-
snapshot:
|
|
65623
|
+
snapshot: page.text + note,
|
|
65347
65624
|
refs: Object.keys(refs).length,
|
|
65348
65625
|
epoch: record.epoch,
|
|
65626
|
+
scoped,
|
|
65627
|
+
frames_in_scope: framesInScope,
|
|
65628
|
+
total_lines: page.totalLines,
|
|
65629
|
+
matched_lines: page.matchedLines,
|
|
65630
|
+
returned_lines: page.returnedLines,
|
|
65631
|
+
start: page.start,
|
|
65632
|
+
limit: page.limit,
|
|
65633
|
+
search: page.search,
|
|
65349
65634
|
...pageOf(record.view)
|
|
65350
65635
|
};
|
|
65351
65636
|
}
|
|
@@ -65596,6 +65881,22 @@ async function nodeIdForSelector(ctx, view, selector) {
|
|
|
65596
65881
|
}
|
|
65597
65882
|
return queried.nodeId;
|
|
65598
65883
|
}
|
|
65884
|
+
async function backendNodeIdForSelector(ctx, view, selector) {
|
|
65885
|
+
const nodeId = await nodeIdForSelector(ctx, view, selector);
|
|
65886
|
+
const described = await ctx.cdp.send(
|
|
65887
|
+
view.webContents,
|
|
65888
|
+
"DOM.describeNode",
|
|
65889
|
+
{ nodeId, depth: 0 }
|
|
65890
|
+
);
|
|
65891
|
+
const backendNodeId = described?.node?.backendNodeId;
|
|
65892
|
+
if (backendNodeId === void 0) {
|
|
65893
|
+
throw new BridgeCommandError(
|
|
65894
|
+
"element_not_found",
|
|
65895
|
+
`selector ${selector} has no backend node id`
|
|
65896
|
+
);
|
|
65897
|
+
}
|
|
65898
|
+
return backendNodeId;
|
|
65899
|
+
}
|
|
65599
65900
|
const CLICK_FUNCTION = `function () {
|
|
65600
65901
|
const r = this.getBoundingClientRect();
|
|
65601
65902
|
const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
|
|
@@ -65694,9 +65995,33 @@ const READ_VALUE_FUNCTION = `function () {
|
|
|
65694
65995
|
return String(this.textContent || '');
|
|
65695
65996
|
}`;
|
|
65696
65997
|
const SNAPSHOT_REF = /^e\d+$/;
|
|
65998
|
+
function resolvedFields(node) {
|
|
65999
|
+
return node.resolvedBy === "locator" ? {
|
|
66000
|
+
resolved: {
|
|
66001
|
+
by: "locator",
|
|
66002
|
+
role: node.role ?? "",
|
|
66003
|
+
name: node.name ?? "",
|
|
66004
|
+
matched: node.matched ?? 1
|
|
66005
|
+
}
|
|
66006
|
+
} : {};
|
|
66007
|
+
}
|
|
65697
66008
|
function frameFields(node) {
|
|
65698
66009
|
return node.frame ? { frame_origin: node.frame.origin ?? "" } : {};
|
|
65699
66010
|
}
|
|
66011
|
+
async function readAccessibilityTree(ctx, contents) {
|
|
66012
|
+
await ctx.cdp.send(contents, "Accessibility.enable", {});
|
|
66013
|
+
try {
|
|
66014
|
+
const tree = await ctx.cdp.send(
|
|
66015
|
+
contents,
|
|
66016
|
+
"Accessibility.getFullAXTree",
|
|
66017
|
+
{}
|
|
66018
|
+
);
|
|
66019
|
+
return Array.isArray(tree?.nodes) ? tree.nodes : [];
|
|
66020
|
+
} finally {
|
|
66021
|
+
await ctx.cdp.send(contents, "Accessibility.disable", {}).catch(() => {
|
|
66022
|
+
});
|
|
66023
|
+
}
|
|
66024
|
+
}
|
|
65700
66025
|
async function resolveNode(ctx, record, target2) {
|
|
65701
66026
|
const view = record.view;
|
|
65702
66027
|
const contents = view.webContents;
|
|
@@ -65721,6 +66046,39 @@ async function resolveNode(ctx, record, target2) {
|
|
|
65721
66046
|
}
|
|
65722
66047
|
return finishTop(ctx, contents, target2, pushedId, ref.frameOrigin);
|
|
65723
66048
|
}
|
|
66049
|
+
const locator = parseLocator(target2);
|
|
66050
|
+
if (locator) {
|
|
66051
|
+
const nodes = await readAccessibilityTree(ctx, contents);
|
|
66052
|
+
const hit = resolveLocator(nodes, locator);
|
|
66053
|
+
if (!hit) {
|
|
66054
|
+
throw new BridgeCommandError(
|
|
66055
|
+
"element_not_found",
|
|
66056
|
+
`no element matches ${target2}`,
|
|
66057
|
+
{ candidates: locatorSuggestions(nodes, target2), matched: 0 }
|
|
66058
|
+
);
|
|
66059
|
+
}
|
|
66060
|
+
await ctx.cdp.send(contents, "DOM.getDocument", { depth: 0 });
|
|
66061
|
+
const pushed = await ctx.cdp.send(
|
|
66062
|
+
contents,
|
|
66063
|
+
"DOM.pushNodesByBackendIdsToFrontend",
|
|
66064
|
+
{ backendNodeIds: [hit.backendNodeId] }
|
|
66065
|
+
);
|
|
66066
|
+
const nodeId2 = pushed?.nodeIds?.[0];
|
|
66067
|
+
if (nodeId2 === void 0) {
|
|
66068
|
+
throw new BridgeCommandError(
|
|
66069
|
+
"element_not_found",
|
|
66070
|
+
`${target2} is no longer in the document`
|
|
66071
|
+
);
|
|
66072
|
+
}
|
|
66073
|
+
const resolved = await finishTop(ctx, contents, target2, nodeId2);
|
|
66074
|
+
return {
|
|
66075
|
+
...resolved,
|
|
66076
|
+
resolvedBy: "locator",
|
|
66077
|
+
role: hit.role,
|
|
66078
|
+
name: hit.name,
|
|
66079
|
+
matched: hit.matched
|
|
66080
|
+
};
|
|
66081
|
+
}
|
|
65724
66082
|
const hops = parseFrameHops(target2);
|
|
65725
66083
|
if (hops) {
|
|
65726
66084
|
const hit = await resolveHops(ctx, contents, hops);
|
|
@@ -65733,8 +66091,8 @@ async function resolveNode(ctx, record, target2) {
|
|
|
65733
66091
|
if (!(error instanceof BridgeCommandError) || !TOP_MISS.test(error.message)) {
|
|
65734
66092
|
throw error;
|
|
65735
66093
|
}
|
|
65736
|
-
const { matches, walk } = await searchFrames(ctx, contents, target2);
|
|
65737
|
-
if (
|
|
66094
|
+
const { matches: matches2, walk } = await searchFrames(ctx, contents, target2);
|
|
66095
|
+
if (matches2.length === 0) {
|
|
65738
66096
|
if (!walk.truncated && walk.skipped === 0 && walk.denied === 0)
|
|
65739
66097
|
throw error;
|
|
65740
66098
|
throw new BridgeCommandError(
|
|
@@ -65742,21 +66100,21 @@ async function resolveNode(ctx, record, target2) {
|
|
|
65742
66100
|
`selector ${target2} matched nothing in the page itself or the frames searched (${walkNote(walk)}); address the frame explicitly as <iframe-selector> ${FRAME_HOP} <selector>`
|
|
65743
66101
|
);
|
|
65744
66102
|
}
|
|
65745
|
-
if (
|
|
65746
|
-
const candidate = candidatePath(
|
|
66103
|
+
if (matches2.length === 1 && (walk.truncated || walk.skipped > 0)) {
|
|
66104
|
+
const candidate = candidatePath(matches2[0].scope, target2);
|
|
65747
66105
|
throw new BridgeCommandError(
|
|
65748
66106
|
"element_not_found",
|
|
65749
66107
|
`selector ${target2} matched nothing in the page itself and one element in the frames searched, but not every frame was searched (${walkNote(walk)}), so nothing was done; if this is the one, name it: ${candidate}`,
|
|
65750
66108
|
{ candidates: [candidate] }
|
|
65751
66109
|
);
|
|
65752
66110
|
}
|
|
65753
|
-
if (
|
|
65754
|
-
const candidates =
|
|
66111
|
+
if (matches2.length > 1) {
|
|
66112
|
+
const candidates = matches2.map(
|
|
65755
66113
|
(match) => candidatePath(match.scope, target2)
|
|
65756
66114
|
);
|
|
65757
66115
|
throw new BridgeCommandError(
|
|
65758
66116
|
"element_not_found",
|
|
65759
|
-
`selector ${target2} matched nothing in the page itself and ${
|
|
66117
|
+
`selector ${target2} matched nothing in the page itself and ${matches2.length} elements inside its frames, so nothing was done; name one: ${candidates.join(", ")}`,
|
|
65760
66118
|
{ candidates }
|
|
65761
66119
|
);
|
|
65762
66120
|
}
|
|
@@ -65764,8 +66122,8 @@ async function resolveNode(ctx, record, target2) {
|
|
|
65764
66122
|
ctx,
|
|
65765
66123
|
contents,
|
|
65766
66124
|
target2,
|
|
65767
|
-
|
|
65768
|
-
|
|
66125
|
+
matches2[0].scope,
|
|
66126
|
+
matches2[0].nodeId
|
|
65769
66127
|
);
|
|
65770
66128
|
}
|
|
65771
66129
|
return finishTop(ctx, contents, target2, nodeId);
|
|
@@ -65918,6 +66276,7 @@ async function click(ctx, params) {
|
|
|
65918
66276
|
return {
|
|
65919
66277
|
navigated: navigationSeen || after.url !== before,
|
|
65920
66278
|
...frameFields(node),
|
|
66279
|
+
...resolvedFields(node),
|
|
65921
66280
|
...after
|
|
65922
66281
|
};
|
|
65923
66282
|
}
|
|
@@ -65930,7 +66289,12 @@ async function type(ctx, params) {
|
|
|
65930
66289
|
const typed = await typeInto(ctx, contents, node, text, target2);
|
|
65931
66290
|
if (typed) {
|
|
65932
66291
|
ctx.registry.touch(record);
|
|
65933
|
-
return {
|
|
66292
|
+
return {
|
|
66293
|
+
...typed,
|
|
66294
|
+
...frameFields(node),
|
|
66295
|
+
...resolvedFields(node),
|
|
66296
|
+
...pageOf(record.view)
|
|
66297
|
+
};
|
|
65934
66298
|
}
|
|
65935
66299
|
const frame = await iframeScopeOf(ctx, contents, node);
|
|
65936
66300
|
if (frame) {
|