local-operator-ui 0.41.0 → 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.
Files changed (96) hide show
  1. package/out/main/index.js +390 -50
  2. package/out/preload/index.js +19 -0
  3. package/out/renderer/assets/{_basePickBy--UFblcLV.js → _basePickBy-BgapP5T6.js} +1 -1
  4. package/out/renderer/assets/{_baseUniq-Ct7pRnI4.js → _baseUniq-B9rnfho3.js} +1 -1
  5. package/out/renderer/assets/{agent-details-page-Col1VcjS.js → agent-details-page-CKRUVtjJ.js} +2 -2
  6. package/out/renderer/assets/{agent-hub-page-CTPn6yGs.js → agent-hub-page-5qLVOZEV.js} +2 -2
  7. package/out/renderer/assets/{agents-page-CBWj1DTr.js → agents-page-tQooOOKH.js} +3 -3
  8. package/out/renderer/assets/{arc-B-YNVaQW.js → arc-Feq-cl9G.js} +1 -1
  9. package/out/renderer/assets/{architectureDiagram-IEHRJDOE-DCzmuMLj.js → architectureDiagram-IEHRJDOE-BmZeJuzA.js} +1 -1
  10. package/out/renderer/assets/{blockDiagram-JOT3LUYC-f1GS2_U0.js → blockDiagram-JOT3LUYC-DEqkKuOE.js} +1 -1
  11. package/out/renderer/assets/{book-open-Cb4F-cRs.js → book-open-C1uak1LZ.js} +1 -1
  12. package/out/renderer/assets/browser-page-CB-_usY1.js +1 -0
  13. package/out/renderer/assets/{browser-webauthn-prompt-ghcPWp0R.js → browser-webauthn-prompt-CKUBOIHd.js} +1 -1
  14. package/out/renderer/assets/{building-2-C_YBTC7O.js → building-2-Bpz1qaDa.js} +1 -1
  15. package/out/renderer/assets/{c4Diagram-VJAJSXHY-BlePs8Im.js → c4Diagram-VJAJSXHY-EbhUbSdf.js} +1 -1
  16. package/out/renderer/assets/channel-CPGK3lub.js +1 -0
  17. package/out/renderer/assets/{chunk-4BMEZGHF-Bse1IaHb.js → chunk-4BMEZGHF-DIk7XDrx.js} +1 -1
  18. package/out/renderer/assets/{chunk-A2AXSNBT-CncpJ5It.js → chunk-A2AXSNBT-D_MflthZ.js} +1 -1
  19. package/out/renderer/assets/{chunk-AEK57VVT-37Z6jWz2.js → chunk-AEK57VVT-C0iLgwbv.js} +1 -1
  20. package/out/renderer/assets/{chunk-D6G4REZN-BR9ZpBMV.js → chunk-D6G4REZN-BbFuFCzc.js} +1 -1
  21. package/out/renderer/assets/{chunk-RZ5BOZE2-KrZ6g0pV.js → chunk-RZ5BOZE2-BxQo8VeZ.js} +1 -1
  22. package/out/renderer/assets/{chunk-XZIHB7SX-BUwRYMe9.js → chunk-XZIHB7SX-DnNtYGsR.js} +1 -1
  23. package/out/renderer/assets/classDiagram-GIVACNV2-hDc6ku-l.js +1 -0
  24. package/out/renderer/assets/classDiagram-v2-COTLJTTW-hDc6ku-l.js +1 -0
  25. package/out/renderer/assets/clone--PuuOIog.js +1 -0
  26. package/out/renderer/assets/{console-mirror-DPVG6sWK.js → console-mirror-Bxl6t4e9.js} +1 -1
  27. package/out/renderer/assets/{consoleCapture-Coky9UhD.js → consoleCapture-BzSftKjg.js} +1 -1
  28. package/out/renderer/assets/{conversation-input-sync-C2vqs6ad.js → conversation-input-sync-MZPvyAzc.js} +239 -239
  29. package/out/renderer/assets/{dagre-OKDRZEBW-CGv1CEcm.js → dagre-OKDRZEBW-qejdp-TF.js} +1 -1
  30. package/out/renderer/assets/{diagram-SSKATNLV-u_zFGYu8.js → diagram-SSKATNLV-qHrLhzXc.js} +1 -1
  31. package/out/renderer/assets/{diagram-VNBRO52H-Bme6bFvQ.js → diagram-VNBRO52H-q0teJTmh.js} +1 -1
  32. package/out/renderer/assets/{erDiagram-Q7BY3M3F-B-KkjVtc.js → erDiagram-Q7BY3M3F-DI6rp9FR.js} +1 -1
  33. package/out/renderer/assets/{error-boundary-DJSaJHcb.js → error-boundary-ZYkSCpZC.js} +2 -2
  34. package/out/renderer/assets/{flowDiagram-4HSFHLVR-CSZy2b_d.js → flowDiagram-4HSFHLVR-xVi21DAI.js} +1 -1
  35. package/out/renderer/assets/{ganttDiagram-APWFNJXF-CpYOSVKU.js → ganttDiagram-APWFNJXF-BUKGBOB_.js} +1 -1
  36. package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-WOOSBsBb.js → gitGraphDiagram-7IBYFJ6S-CdE3ZeMn.js} +1 -1
  37. package/out/renderer/assets/{graph-Du8nFp-Q.js → graph-CRaHrZRK.js} +1 -1
  38. package/out/renderer/assets/hash-BN0ECl3H.js +6 -0
  39. package/out/renderer/assets/{heart-CVGkdUzT.js → heart-tKYqMVIH.js} +1 -1
  40. package/out/renderer/assets/{index-fw54FEnm.js → index-B9E-fwX4.js} +1 -1
  41. package/out/renderer/assets/index-BDzV3bGH.js +57 -0
  42. package/out/renderer/assets/{index-D8L83jtw.js → index-DknTGnAk.js} +206 -206
  43. package/out/renderer/assets/{index-AGCqaeOI.js → index-FsaxlHdZ.js} +1 -1
  44. package/out/renderer/assets/index-ZovyVTxQ.css +1 -0
  45. package/out/renderer/assets/{infoDiagram-PH2N3AL5-BprulvMk.js → infoDiagram-PH2N3AL5-pOK9P20l.js} +1 -1
  46. package/out/renderer/assets/{installer-muZhWyyS.js → installer-Dw1P6j8q.js} +1 -1
  47. package/out/renderer/assets/{journeyDiagram-U35MCT3I-DfdLRQAF.js → journeyDiagram-U35MCT3I-D5Sg1JPA.js} +1 -1
  48. package/out/renderer/assets/{kanban-definition-NDS4AKOZ-R6IsuYWB.js → kanban-definition-NDS4AKOZ-BfhWqBCl.js} +1 -1
  49. package/out/renderer/assets/{layout-05Xak_7z.js → layout-IqsTm240.js} +1 -1
  50. package/out/renderer/assets/{legacy-agents-page-Dpl33Kla.js → legacy-agents-page-bdH6oKjE.js} +5 -5
  51. package/out/renderer/assets/library-page-DDvrG_aA.js +157 -0
  52. package/out/renderer/assets/{mermaid.core-BzKfajYZ.js → mermaid.core-D0YPuNli.js} +5 -5
  53. package/out/renderer/assets/{mesh-page-D6ZzFOeG.js → mesh-page-DYFNof_0.js} +1 -1
  54. package/out/renderer/assets/{mindmap-definition-ALO5MXBD-Dn_l0i7j.js → mindmap-definition-ALO5MXBD-Tx5iMDRU.js} +1 -1
  55. package/out/renderer/assets/{mini-BgJE9L7J.js → mini-BoZCnSK9.js} +1 -1
  56. package/out/renderer/assets/{notebook-pen-CtAKsfVm.js → notebook-pen-C3CwzwGA.js} +1 -1
  57. package/out/renderer/assets/{org-access-BHt55LAw.js → org-access-DoZK5gF3.js} +1 -1
  58. package/out/renderer/assets/{org-surface-gate-CqFJQYmV.js → org-surface-gate-Dy0B7mtt.js} +1 -1
  59. package/out/renderer/assets/{page-header-BlIvE-Ti.js → page-header-6mrV9W-E.js} +1 -1
  60. package/out/renderer/assets/path-utils-CRYGE4mK.js +58 -0
  61. package/out/renderer/assets/{pieDiagram-IB7DONF6-_W_OzAAk.js → pieDiagram-IB7DONF6-D0rED3_3.js} +1 -1
  62. package/out/renderer/assets/{projects-page-DtZ_g9gZ.js → projects-page-D7j1GOvI.js} +1 -1
  63. package/out/renderer/assets/{publication-validation-D7f3xAgF.js → publication-validation-CLbFS0n9.js} +1 -1
  64. package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-FQ5Wvxqm.js → quadrantDiagram-7GDLP6J5-D8jKSQt5.js} +1 -1
  65. package/out/renderer/assets/{radar-MK3ICKWK-BRufXucA.js → radar-MK3ICKWK-Co2EJbaJ.js} +1 -1
  66. package/out/renderer/assets/{radient-auth-buttons-7i7blC-7.js → radient-auth-buttons-B11cdRmS.js} +1 -1
  67. package/out/renderer/assets/{requirementDiagram-KVF5MWMF-CHO8Cq1H.js → requirementDiagram-KVF5MWMF-BI13h11j.js} +1 -1
  68. package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-C4JDJOwX.js → sankeyDiagram-QLVOVGJD-D4hZ6_ML.js} +1 -1
  69. package/out/renderer/assets/{schedules-page-6tPgFgS_.js → schedules-page-DFfDDHYC.js} +1 -1
  70. package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-BFf3HnKw.js → sequenceDiagram-X6HHIX6F-U6CqBtco.js} +1 -1
  71. package/out/renderer/assets/{settings-page-CXOFCx8w.js → settings-page-CZ7NUDoe.js} +1 -1
  72. package/out/renderer/assets/{smartart-crAq3DvJ.js → smartart-BVm_cEaq.js} +1 -1
  73. package/out/renderer/assets/{stateDiagram-DGXRK772-BqFVSIKA.js → stateDiagram-DGXRK772-DBg11bkx.js} +1 -1
  74. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-jmaink9i.js +1 -0
  75. package/out/renderer/assets/team-bridge-page-u_OqiZGS.js +16 -0
  76. package/out/renderer/assets/{timeline-definition-BDJGKUSR-Cp3uYUSs.js → timeline-definition-BDJGKUSR-WQ6aYia6.js} +1 -1
  77. package/out/renderer/assets/{use-download-agent-mutation-C_W8yx0C.js → use-download-agent-mutation-ZoivWizY.js} +2 -2
  78. package/out/renderer/assets/{use-session-snapshot-vFZD5qIO.js → use-session-snapshot-CdYiirKJ.js} +1 -1
  79. package/out/renderer/assets/{xychartDiagram-VJFVF3MP-DFcICu1Q.js → xychartDiagram-VJFVF3MP-f11BpHer.js} +1 -1
  80. package/out/renderer/console-capture.html +5 -5
  81. package/out/renderer/index.html +7 -7
  82. package/out/renderer/installer.html +4 -4
  83. package/out/renderer/mini.html +7 -7
  84. package/package.json +4 -3
  85. package/out/renderer/assets/browser-page-BfJd3-qS.js +0 -1
  86. package/out/renderer/assets/channel-BFAjMbH6.js +0 -1
  87. package/out/renderer/assets/classDiagram-GIVACNV2-CmW0Ezdi.js +0 -1
  88. package/out/renderer/assets/classDiagram-v2-COTLJTTW-CmW0Ezdi.js +0 -1
  89. package/out/renderer/assets/clone-B_pc7cSP.js +0 -1
  90. package/out/renderer/assets/hash--PQTQMu2.js +0 -6
  91. package/out/renderer/assets/index-ALGblIL0.css +0 -1
  92. package/out/renderer/assets/index-BYeiLB51.js +0 -57
  93. package/out/renderer/assets/library-page-BNrffbLi.js +0 -157
  94. package/out/renderer/assets/path-utils-CYBk4q7C.js +0 -58
  95. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-aaVC-oiG.js +0 -1
  96. package/out/renderer/assets/team-bridge-page-BgjJrT3v.js +0 -26
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 ? { body: { tenant_id: 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 }
@@ -38790,9 +38834,6 @@ const enUiTeamBridge = {
38790
38834
  "ui.teamBridge.section.chiefs_empty": "No teammate has an agent on Team Bridge yet.",
38791
38835
  "ui.teamBridge.chief.label": "{agent} ({person})",
38792
38836
  "ui.teamBridge.chief.fallback": "Chief of staff",
38793
- "ui.teamBridge.chief.unnamed": "{person}’s chief of staff",
38794
- "ui.teamBridge.message.sending": "Sending…",
38795
- "ui.teamBridge.message.failed": "Not sent",
38796
38837
  "ui.teamBridge.people.self_named": "{name} (you)",
38797
38838
  "ui.teamBridge.row.menu": "More actions for {name}",
38798
38839
  "ui.teamBridge.row.start_group": "Start a group conversation",
@@ -42434,9 +42475,6 @@ const esUiTeamBridge = {
42434
42475
  "ui.teamBridge.section.chiefs_empty": "Ningún miembro del equipo tiene todavía un agente en Team Bridge.",
42435
42476
  "ui.teamBridge.chief.label": "{agent} ({person})",
42436
42477
  "ui.teamBridge.chief.fallback": "Jefe de gabinete",
42437
- "ui.teamBridge.chief.unnamed": "Jefe de gabinete de {person}",
42438
- "ui.teamBridge.message.sending": "Enviando…",
42439
- "ui.teamBridge.message.failed": "No enviado",
42440
42478
  "ui.teamBridge.people.self_named": "{name} (tú)",
42441
42479
  "ui.teamBridge.row.menu": "Más acciones para {name}",
42442
42480
  "ui.teamBridge.row.start_group": "Iniciar una conversación grupal",
@@ -46078,9 +46116,6 @@ const frUiTeamBridge = {
46078
46116
  "ui.teamBridge.section.chiefs_empty": "Aucun membre de l’équipe n’a encore d’agent sur Team Bridge.",
46079
46117
  "ui.teamBridge.chief.label": "{agent} ({person})",
46080
46118
  "ui.teamBridge.chief.fallback": "Cheffe de cabinet",
46081
- "ui.teamBridge.chief.unnamed": "Cheffe de cabinet ({person})",
46082
- "ui.teamBridge.message.sending": "Envoi…",
46083
- "ui.teamBridge.message.failed": "Non envoyé",
46084
46119
  "ui.teamBridge.people.self_named": "{name} (vous)",
46085
46120
  "ui.teamBridge.row.menu": "Plus d’actions pour {name}",
46086
46121
  "ui.teamBridge.row.start_group": "Démarrer une conversation de groupe",
@@ -49680,9 +49715,6 @@ const hiUiTeamBridge = {
49680
49715
  "ui.teamBridge.section.chiefs_empty": "अभी किसी टीम सदस्य का एजेंट Team Bridge पर नहीं है।",
49681
49716
  "ui.teamBridge.chief.label": "{agent} ({person})",
49682
49717
  "ui.teamBridge.chief.fallback": "चीफ़ ऑफ़ स्टाफ़",
49683
- "ui.teamBridge.chief.unnamed": "{person} के चीफ़ ऑफ़ स्टाफ़",
49684
- "ui.teamBridge.message.sending": "भेजा जा रहा है…",
49685
- "ui.teamBridge.message.failed": "भेजा नहीं गया",
49686
49718
  "ui.teamBridge.people.self_named": "{name} (आप)",
49687
49719
  "ui.teamBridge.row.menu": "{name} के लिए और कार्रवाइयाँ",
49688
49720
  "ui.teamBridge.row.start_group": "समूह बातचीत शुरू करें",
@@ -53302,9 +53334,6 @@ const ruUiTeamBridge = {
53302
53334
  "ui.teamBridge.section.chiefs_empty": "Ни у одного участника команды пока нет агента в Team Bridge.",
53303
53335
  "ui.teamBridge.chief.label": "{agent} ({person})",
53304
53336
  "ui.teamBridge.chief.fallback": "Координатор",
53305
- "ui.teamBridge.chief.unnamed": "Координатор ({person})",
53306
- "ui.teamBridge.message.sending": "Отправка…",
53307
- "ui.teamBridge.message.failed": "Не отправлено",
53308
53337
  "ui.teamBridge.people.self_named": "{name} (вы)",
53309
53338
  "ui.teamBridge.row.menu": "Другие действия для {name}",
53310
53339
  "ui.teamBridge.row.start_group": "Начать групповой разговор",
@@ -56924,9 +56953,6 @@ const urUiTeamBridge = {
56924
56953
  "ui.teamBridge.section.chiefs_empty": "ابھی ٹیم کے کسی رکن کا ایجنٹ Team Bridge پر نہیں۔",
56925
56954
  "ui.teamBridge.chief.label": "{agent} ({person})",
56926
56955
  "ui.teamBridge.chief.fallback": "چیف آف اسٹاف",
56927
- "ui.teamBridge.chief.unnamed": "{person} کے چیف آف اسٹاف",
56928
- "ui.teamBridge.message.sending": "بھیجا جا رہا ہے…",
56929
- "ui.teamBridge.message.failed": "بھیجا نہیں گیا",
56930
56956
  "ui.teamBridge.people.self_named": "{name} (آپ)",
56931
56957
  "ui.teamBridge.row.menu": "{name} کے مزید اقدامات",
56932
56958
  "ui.teamBridge.row.start_group": "گروپ گفتگو شروع کریں",
@@ -60355,9 +60381,6 @@ const viUiTeamBridge = {
60355
60381
  "ui.teamBridge.section.chiefs_empty": "Chưa có đồng nghiệp nào đưa tác nhân lên Team Bridge.",
60356
60382
  "ui.teamBridge.chief.label": "{agent} ({person})",
60357
60383
  "ui.teamBridge.chief.fallback": "Chánh văn phòng",
60358
- "ui.teamBridge.chief.unnamed": "Chánh văn phòng của {person}",
60359
- "ui.teamBridge.message.sending": "Đang gửi…",
60360
- "ui.teamBridge.message.failed": "Chưa gửi được",
60361
60384
  "ui.teamBridge.people.self_named": "{name} (bạn)",
60362
60385
  "ui.teamBridge.row.menu": "Thao tác khác cho {name}",
60363
60386
  "ui.teamBridge.row.start_group": "Bắt đầu trò chuyện nhóm",
@@ -63999,9 +64022,6 @@ const zhCNUiTeamBridge = {
63999
64022
  "ui.teamBridge.section.chiefs_empty": "还没有团队成员将智能体接入Team Bridge。",
64000
64023
  "ui.teamBridge.chief.label": "{agent}({person})",
64001
64024
  "ui.teamBridge.chief.fallback": "首席助理",
64002
- "ui.teamBridge.chief.unnamed": "{person}的首席助理",
64003
- "ui.teamBridge.message.sending": "发送中……",
64004
- "ui.teamBridge.message.failed": "未发送",
64005
64025
  "ui.teamBridge.people.self_named": "{name}(你)",
64006
64026
  "ui.teamBridge.row.menu": "{name}的更多操作",
64007
64027
  "ui.teamBridge.row.start_group": "发起群组对话",
@@ -64830,6 +64850,158 @@ function pageOf(view) {
64830
64850
  title: view.webContents.isDestroyed() ? "" : view.webContents.getTitle()
64831
64851
  };
64832
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
+ }
64833
65005
  const FRAME_HOP = ">>>";
64834
65006
  const MAX_FRAME_DEPTH = 3;
64835
65007
  const MAX_FRAMES_SEARCHED = 20;
@@ -65080,7 +65252,7 @@ async function resolveHops(ctx, contents, hops) {
65080
65252
  return { scope, nodeId };
65081
65253
  }
65082
65254
  async function searchFrames(ctx, contents, selector) {
65083
- const matches = [];
65255
+ const matches2 = [];
65084
65256
  const walk = await listFrames(ctx, contents);
65085
65257
  for (const scope of walk.frames) {
65086
65258
  const nodeId = await queryIn(ctx, contents, scope, selector).catch(
@@ -65089,9 +65261,9 @@ async function searchFrames(ctx, contents, selector) {
65089
65261
  return 0;
65090
65262
  }
65091
65263
  );
65092
- if (nodeId) matches.push({ scope, nodeId });
65264
+ if (nodeId) matches2.push({ scope, nodeId });
65093
65265
  }
65094
- return { matches, walk };
65266
+ return { matches: matches2, walk };
65095
65267
  }
65096
65268
  async function listFrames(ctx, contents) {
65097
65269
  const walk = {
@@ -65226,24 +65398,46 @@ async function editableInFrame(ctx, contents, scope, target2) {
65226
65398
  }
65227
65399
  const LANDMARKS = /* @__PURE__ */ new Set(["banner", "main", "navigation", "complementary", "contentinfo", "form", "region"]);
65228
65400
  const INTERACTIVE = /* @__PURE__ */ new Set(["button", "link", "textbox", "checkbox", "radio", "combobox", "menuitem", "tab", "switch", "slider", "spinbutton"]);
65229
- function compactAX(nodes, epoch) {
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 = {}) {
65230
65414
  const byId = new Map(nodes.map((node) => [node.nodeId, node]));
65231
65415
  const refs = {};
65232
65416
  const lines = [];
65233
65417
  let sequence = 0;
65418
+ const scopeId = options.rootBackendNodeId;
65419
+ let scopeAt = null;
65420
+ let framesInScope = 0;
65234
65421
  const visited = /* @__PURE__ */ new Set();
65235
65422
  function visit2(node, depth) {
65236
65423
  if (visited.has(node.nodeId)) return;
65237
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;
65238
65430
  if (node.ignored) {
65239
65431
  for (const child of node.childIds ?? []) {
65240
65432
  const found = byId.get(child);
65241
65433
  if (found) visit2(found, depth);
65242
65434
  }
65435
+ scopeAt = savedScope;
65243
65436
  return;
65244
65437
  }
65245
65438
  const role = String(node.role?.value ?? "");
65246
65439
  const name = String(node.name?.value ?? "").trim();
65440
+ if (inside2 && role === "Iframe") framesInScope += 1;
65247
65441
  const focusable = node.properties?.some((property) => property.name === "focusable" && property.value.value === true);
65248
65442
  const interesting = INTERACTIVE.has(role) || LANDMARKS.has(role) || focusable || Boolean(name && role !== "StaticText");
65249
65443
  if (interesting) {
@@ -65252,16 +65446,54 @@ function compactAX(nodes, epoch) {
65252
65446
  ref = `e${++sequence}`;
65253
65447
  refs[ref] = { backendNodeId: node.backendDOMNodeId, epoch };
65254
65448
  }
65255
- lines.push(`${" ".repeat(depth)}- ${role || "node"}${name ? ` ${JSON.stringify(name)}` : ""}${ref ? ` [${ref}]` : ""}`);
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
+ }
65256
65453
  }
65257
65454
  for (const child of node.childIds ?? []) {
65258
65455
  const found = byId.get(child);
65259
65456
  if (found) visit2(found, interesting ? depth + 1 : depth);
65260
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 };
65261
65463
  }
65262
65464
  const childIds = new Set(nodes.flatMap((node) => node.childIds ?? []));
65263
65465
  for (const root of nodes.filter((node) => !childIds.has(node.nodeId))) visit2(root, 0);
65264
- return { snapshot: lines.join("\n"), refs };
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
+ };
65265
65497
  }
65266
65498
  const PAGE_OVERLAP_PX = 80;
65267
65499
  function defaultScrollExpression() {
@@ -65341,6 +65573,8 @@ async function read(ctx, params) {
65341
65573
  async function snapshot(ctx, params) {
65342
65574
  const record = ctx.registry.requireSurface(params.tab);
65343
65575
  const contents = record.view.webContents;
65576
+ const scope = stringParam(params, "selector");
65577
+ const rootBackendNodeId = scope ? await backendNodeIdForSelector(ctx, record.view, scope) : void 0;
65344
65578
  await ctx.cdp.send(contents, "Accessibility.enable", {});
65345
65579
  let nodes = [];
65346
65580
  try {
@@ -65354,22 +65588,49 @@ async function snapshot(ctx, params) {
65354
65588
  await ctx.cdp.send(contents, "Accessibility.disable", {}).catch(() => {
65355
65589
  });
65356
65590
  }
65357
- const { snapshot: topRendered, refs: topRefs } = compactAX(
65358
- nodes,
65359
- record.epoch
65360
- );
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
+ }
65361
65603
  const refs = { ...topRefs };
65362
65604
  let rendered = topRendered;
65363
- if (nodes.some(isFrameNode)) {
65605
+ if (!scope && nodes.some(isFrameNode)) {
65364
65606
  const blocks = await frameSnapshots(ctx, record, nodes, refs);
65365
65607
  if (blocks.length) rendered = [rendered, ...blocks].join("\n");
65366
65608
  }
65367
65609
  record.refs = refs;
65368
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
+ });
65369
65622
  return {
65370
- snapshot: rendered,
65623
+ snapshot: page.text + note,
65371
65624
  refs: Object.keys(refs).length,
65372
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,
65373
65634
  ...pageOf(record.view)
65374
65635
  };
65375
65636
  }
@@ -65620,6 +65881,22 @@ async function nodeIdForSelector(ctx, view, selector) {
65620
65881
  }
65621
65882
  return queried.nodeId;
65622
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
+ }
65623
65900
  const CLICK_FUNCTION = `function () {
65624
65901
  const r = this.getBoundingClientRect();
65625
65902
  const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
@@ -65718,9 +65995,33 @@ const READ_VALUE_FUNCTION = `function () {
65718
65995
  return String(this.textContent || '');
65719
65996
  }`;
65720
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
+ }
65721
66008
  function frameFields(node) {
65722
66009
  return node.frame ? { frame_origin: node.frame.origin ?? "" } : {};
65723
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
+ }
65724
66025
  async function resolveNode(ctx, record, target2) {
65725
66026
  const view = record.view;
65726
66027
  const contents = view.webContents;
@@ -65745,6 +66046,39 @@ async function resolveNode(ctx, record, target2) {
65745
66046
  }
65746
66047
  return finishTop(ctx, contents, target2, pushedId, ref.frameOrigin);
65747
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
+ }
65748
66082
  const hops = parseFrameHops(target2);
65749
66083
  if (hops) {
65750
66084
  const hit = await resolveHops(ctx, contents, hops);
@@ -65757,8 +66091,8 @@ async function resolveNode(ctx, record, target2) {
65757
66091
  if (!(error instanceof BridgeCommandError) || !TOP_MISS.test(error.message)) {
65758
66092
  throw error;
65759
66093
  }
65760
- const { matches, walk } = await searchFrames(ctx, contents, target2);
65761
- if (matches.length === 0) {
66094
+ const { matches: matches2, walk } = await searchFrames(ctx, contents, target2);
66095
+ if (matches2.length === 0) {
65762
66096
  if (!walk.truncated && walk.skipped === 0 && walk.denied === 0)
65763
66097
  throw error;
65764
66098
  throw new BridgeCommandError(
@@ -65766,21 +66100,21 @@ async function resolveNode(ctx, record, target2) {
65766
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>`
65767
66101
  );
65768
66102
  }
65769
- if (matches.length === 1 && (walk.truncated || walk.skipped > 0)) {
65770
- const candidate = candidatePath(matches[0].scope, target2);
66103
+ if (matches2.length === 1 && (walk.truncated || walk.skipped > 0)) {
66104
+ const candidate = candidatePath(matches2[0].scope, target2);
65771
66105
  throw new BridgeCommandError(
65772
66106
  "element_not_found",
65773
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}`,
65774
66108
  { candidates: [candidate] }
65775
66109
  );
65776
66110
  }
65777
- if (matches.length > 1) {
65778
- const candidates = matches.map(
66111
+ if (matches2.length > 1) {
66112
+ const candidates = matches2.map(
65779
66113
  (match) => candidatePath(match.scope, target2)
65780
66114
  );
65781
66115
  throw new BridgeCommandError(
65782
66116
  "element_not_found",
65783
- `selector ${target2} matched nothing in the page itself and ${matches.length} elements inside its frames, so nothing was done; name one: ${candidates.join(", ")}`,
66117
+ `selector ${target2} matched nothing in the page itself and ${matches2.length} elements inside its frames, so nothing was done; name one: ${candidates.join(", ")}`,
65784
66118
  { candidates }
65785
66119
  );
65786
66120
  }
@@ -65788,8 +66122,8 @@ async function resolveNode(ctx, record, target2) {
65788
66122
  ctx,
65789
66123
  contents,
65790
66124
  target2,
65791
- matches[0].scope,
65792
- matches[0].nodeId
66125
+ matches2[0].scope,
66126
+ matches2[0].nodeId
65793
66127
  );
65794
66128
  }
65795
66129
  return finishTop(ctx, contents, target2, nodeId);
@@ -65942,6 +66276,7 @@ async function click(ctx, params) {
65942
66276
  return {
65943
66277
  navigated: navigationSeen || after.url !== before,
65944
66278
  ...frameFields(node),
66279
+ ...resolvedFields(node),
65945
66280
  ...after
65946
66281
  };
65947
66282
  }
@@ -65954,7 +66289,12 @@ async function type(ctx, params) {
65954
66289
  const typed = await typeInto(ctx, contents, node, text, target2);
65955
66290
  if (typed) {
65956
66291
  ctx.registry.touch(record);
65957
- return { ...typed, ...frameFields(node), ...pageOf(record.view) };
66292
+ return {
66293
+ ...typed,
66294
+ ...frameFields(node),
66295
+ ...resolvedFields(node),
66296
+ ...pageOf(record.view)
66297
+ };
65958
66298
  }
65959
66299
  const frame = await iframeScopeOf(ctx, contents, node);
65960
66300
  if (frame) {