local-operator-ui 0.36.7 → 0.36.8
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 +556 -20
- package/out/preload/index.js +40 -0
- package/out/renderer/assets/{_basePickBy-Cp4-k2Ra.js → _basePickBy-D11ygq2l.js} +1 -1
- package/out/renderer/assets/{_baseUniq-SW_cXbV_.js → _baseUniq-_Pf0yG1r.js} +1 -1
- package/out/renderer/assets/{agent-details-page-N3zxLs5x.js → agent-details-page-LU973LFV.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-BlZWarvE.js → agent-hub-page-DegTVxlE.js} +2 -2
- package/out/renderer/assets/{agents-page-C7c-PG8v.js → agents-page-B6Y-wB7u.js} +3 -3
- package/out/renderer/assets/{arc-CH4PDipB.js → arc-BedtwWh_.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-YJo8Ggxb.js → architectureDiagram-IEHRJDOE-DyIP0L4b.js} +1 -1
- package/out/renderer/assets/{arrow-up-BB9CxXVA.js → arrow-up-BD8jieeb.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-rOqQnp0E.js → blockDiagram-JOT3LUYC-w5b-ZzdW.js} +1 -1
- package/out/renderer/assets/{book-open-DkVxCJ61.js → book-open-DxzLWerU.js} +1 -1
- package/out/renderer/assets/browser-page-Bm5bblrV.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-Dna4BiM9.js → browser-webauthn-prompt-CbE9FFZv.js} +1 -1
- package/out/renderer/assets/{building-2-CavXM_-r.js → building-2-DtOQfBQY.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-DEPLadlT.js → c4Diagram-VJAJSXHY-CnSFoHWb.js} +1 -1
- package/out/renderer/assets/channel-BJPW3C83.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-klJwtJH4.js → chunk-4BMEZGHF-CY0scau5.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-DRT8OSGB.js → chunk-A2AXSNBT-B_cWmZiK.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-kqK_zO-a.js → chunk-AEK57VVT-BRm1a_Ub.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-CJZaq5OR.js → chunk-D6G4REZN-CmZT-cQT.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-D4tpPnZf.js → chunk-RZ5BOZE2-Cwg1etHt.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-D4Kppo6Q.js → chunk-XZIHB7SX-a-OtMrnF.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BjlJ_E71.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BjlJ_E71.js +1 -0
- package/out/renderer/assets/clone-BuzQaJVT.js +1 -0
- package/out/renderer/assets/{console-mirror-BOyWikJU.js → console-mirror-wrjuOlK5.js} +1 -1
- package/out/renderer/assets/{consoleCapture-Ctr4ZgwO.js → consoleCapture-CGsX86Ez.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-DdFRR8Sk.js → conversation-input-sync-qFePp_gf.js} +271 -271
- package/out/renderer/assets/{dagre-OKDRZEBW-ZzTMDgQF.js → dagre-OKDRZEBW-ujAbOxN1.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-D-OEK7di.js → diagram-SSKATNLV-BGt8bOqa.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-CM6lMapK.js → diagram-VNBRO52H-DGmIp--B.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-2khnybxo.js → erDiagram-Q7BY3M3F-Czgf2xtG.js} +1 -1
- package/out/renderer/assets/{error-boundary-B2fmvLyi.js → error-boundary-CIO9VaTx.js} +2 -2
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-PmXhc4g8.js → flowDiagram-4HSFHLVR-BSuzI5ul.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-DXqSjI8D.js → ganttDiagram-APWFNJXF-DjjvFPP9.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-CE0xYGI6.js → gitGraphDiagram-7IBYFJ6S-qgMylPGx.js} +1 -1
- package/out/renderer/assets/{graph-ydqZFY1l.js → graph-C_PIARec.js} +1 -1
- package/out/renderer/assets/{hash-Dc3JifaZ.js → hash-BTR-wmLC.js} +1 -1
- package/out/renderer/assets/index-B5ZsvNme.js +7 -0
- package/out/renderer/assets/index-B9Z9fABA.js +1 -0
- package/out/renderer/assets/index-BSn66J9q.js +57 -0
- package/out/renderer/assets/index-BzHpKJoz.css +1 -0
- package/out/renderer/assets/index-U5qrTe4P.js +824 -0
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-DOZ3-Qro.js → infoDiagram-PH2N3AL5-CXhZsMAw.js} +1 -1
- package/out/renderer/assets/{installer-DWToCmOf.js → installer-DsBvKWJk.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-DWis6Sd2.js → journeyDiagram-U35MCT3I-BfRBfFPi.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-B9e7wrf9.js → kanban-definition-NDS4AKOZ-BjBPm0Wp.js} +1 -1
- package/out/renderer/assets/{layout-CAcs3Q5o.js → layout-CxH8v5Lh.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-DrGkO870.js → legacy-agents-page-CiirOdbB.js} +5 -5
- package/out/renderer/assets/{library-page-J-oYtewu.js → library-page-CH3E7s4_.js} +3 -3
- package/out/renderer/assets/{mermaid.core-BKDqOsvz.js → mermaid.core-Bx5BMQp8.js} +5 -5
- package/out/renderer/assets/mesh-page-DXuH0pWs.js +1 -0
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-B8ubJP7r.js → mindmap-definition-ALO5MXBD-Cnp-gOUf.js} +1 -1
- package/out/renderer/assets/{mini-CSnAsFlT.js → mini-Cxcx9-Gz.js} +1 -1
- package/out/renderer/assets/{notebook-pen-eF7NwmC0.js → notebook-pen-pmBcBtK5.js} +1 -1
- package/out/renderer/assets/{org-access-CJDIOfTA.js → org-access-BBS-iiGY.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-BFLSYyz1.js → org-surface-gate-B9JbfoNw.js} +1 -1
- package/out/renderer/assets/{page-header-BMDtYfV0.js → page-header-D3rux4P9.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-C4Lho4yQ.js → pieDiagram-IB7DONF6-BXGlHMJD.js} +1 -1
- package/out/renderer/assets/{projects-page-CNUJUnDM.js → projects-page-DjaYWghP.js} +17 -17
- package/out/renderer/assets/publication-validation-Dent7Wyb.js +1 -0
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-DauXMmcp.js → quadrantDiagram-7GDLP6J5-DTE1LofJ.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-_FJ6NjKi.js → radar-MK3ICKWK-C5aiTbpi.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-B4LrTMwy.js → radient-auth-buttons-CD4FRlt9.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-BBMnxRwM.js → requirementDiagram-KVF5MWMF-B-kbiFxO.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-ZAgJNulV.js → sankeyDiagram-QLVOVGJD-8mSg8Gx1.js} +1 -1
- package/out/renderer/assets/{schedules-page-BDxSAX-g.js → schedules-page-M0NGG3zh.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-ixhBbax-.js → sequenceDiagram-X6HHIX6F-Ctz7PqiC.js} +1 -1
- package/out/renderer/assets/settings-page-Cy2SAtSh.js +287 -0
- package/out/renderer/assets/{smartart-CsYIjueA.js → smartart-DmOeXeJs.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-Cyo1D1sd.js → stateDiagram-DGXRK772-x8oSqtIw.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-CUVgaWvm.js +1 -0
- package/out/renderer/assets/{tags-input-chips-DeSDZmGf.js → tags-input-chips-BAP2XNbQ.js} +1 -1
- package/out/renderer/assets/team-bridge-page-CYehSZqj.js +11 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-dHKNC0_-.js → timeline-definition-BDJGKUSR-DZ5836tF.js} +1 -1
- package/out/renderer/assets/ui-preferences-store-oc99NgQT.js +1 -0
- package/out/renderer/assets/{use-download-agent-mutation-Du8Okjj5.js → use-download-agent-mutation-Bgwi0JGB.js} +5 -5
- package/out/renderer/assets/{use-session-snapshot-hoogT7-L.js → use-session-snapshot-DQs7iPEs.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-y9FbutsK.js → xychartDiagram-VJFVF3MP-CQNe5VvP.js} +1 -1
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +7 -7
- package/out/renderer/installer.html +4 -4
- package/out/renderer/mini.html +7 -7
- package/package.json +3 -3
- package/out/renderer/assets/browser-page-Dr5j9bQE.js +0 -1
- package/out/renderer/assets/channel-BUsgjri2.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-YCOFP_Sl.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-YCOFP_Sl.js +0 -1
- package/out/renderer/assets/clone-DVoefRFN.js +0 -1
- package/out/renderer/assets/index-BHi1lUGF.js +0 -1
- package/out/renderer/assets/index-BoPP-Dip.js +0 -7
- package/out/renderer/assets/index-DY17TKlm.js +0 -824
- package/out/renderer/assets/index-Doo51Mbi.js +0 -57
- package/out/renderer/assets/index-JreDTE2U.css +0 -1
- package/out/renderer/assets/mesh-page-CHZ2qVtJ.js +0 -1
- package/out/renderer/assets/publication-validation-5oR6aluM.js +0 -1
- package/out/renderer/assets/settings-page-DpSl6AZf.js +0 -287
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BylkQbLa.js +0 -1
- package/out/renderer/assets/team-bridge-page-BnsNoiEd.js +0 -1
- package/out/renderer/assets/ui-preferences-store-CFbBU1td.js +0 -1
- package/out/renderer/assets/use-memberships-query-C0ico4nv.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -2384,6 +2384,28 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2384
2384
|
conversation_id: id$1,
|
|
2385
2385
|
action: zod.z.enum(["archive", "unarchive", "join", "leave"])
|
|
2386
2386
|
}).strict(),
|
|
2387
|
+
/*
|
|
2388
|
+
* Self-join and the notification preference are their own ops rather than
|
|
2389
|
+
* `lifecycle` actions: the tenant is part of the request (a merge-view row
|
|
2390
|
+
* can name a channel the caller has not joined, and the default tenant
|
|
2391
|
+
* would be the wrong organization), and `notify` is a value, not an
|
|
2392
|
+
* action. The join route is the conversation domain's existing
|
|
2393
|
+
* `POST .../join`; the tenant travels in its body for the same reason the
|
|
2394
|
+
* create/send/read bodies carry one. The notify op rides the READ route's
|
|
2395
|
+
* `notify` field (agent-server #148's shape): it sends no `seq`, so the
|
|
2396
|
+
* cursor cannot move as a side effect of choosing a notification level.
|
|
2397
|
+
*/
|
|
2398
|
+
zod.z.object({
|
|
2399
|
+
op: zod.z.literal("team_bridge.conversations.join"),
|
|
2400
|
+
conversation_id: id$1,
|
|
2401
|
+
tenant_id: id$1.optional()
|
|
2402
|
+
}).strict(),
|
|
2403
|
+
zod.z.object({
|
|
2404
|
+
op: zod.z.literal("team_bridge.conversations.notify"),
|
|
2405
|
+
conversation_id: id$1,
|
|
2406
|
+
tenant_id: id$1.optional(),
|
|
2407
|
+
notify: zod.z.enum(["all", "mention", "mute"])
|
|
2408
|
+
}).strict(),
|
|
2387
2409
|
zod.z.object({
|
|
2388
2410
|
op: zod.z.literal("team_bridge.conversations.members.add"),
|
|
2389
2411
|
conversation_id: id$1,
|
|
@@ -4861,6 +4883,23 @@ function desktopEndpoint(request) {
|
|
|
4861
4883
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/${request.action}`,
|
|
4862
4884
|
method: "POST"
|
|
4863
4885
|
};
|
|
4886
|
+
case "team_bridge.conversations.join":
|
|
4887
|
+
return {
|
|
4888
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/join`,
|
|
4889
|
+
method: "POST",
|
|
4890
|
+
...request.tenant_id ? { body: { tenant_id: request.tenant_id } } : {}
|
|
4891
|
+
};
|
|
4892
|
+
case "team_bridge.conversations.notify":
|
|
4893
|
+
return {
|
|
4894
|
+
/* The read route's notify field (agent-server #148); no `seq`, so
|
|
4895
|
+
this write cannot advance the cursor. */
|
|
4896
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/read`,
|
|
4897
|
+
method: "POST",
|
|
4898
|
+
body: {
|
|
4899
|
+
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
4900
|
+
notify: request.notify
|
|
4901
|
+
}
|
|
4902
|
+
};
|
|
4864
4903
|
case "team_bridge.conversations.members.add": {
|
|
4865
4904
|
const query = new URLSearchParams();
|
|
4866
4905
|
if (request.tenant_id) query.set("tenant_id", request.tenant_id);
|
|
@@ -9070,7 +9109,7 @@ const DESKTOP_STREAM_DETAIL = {
|
|
|
9070
9109
|
refusedWithoutStatus: "The event stream was refused."
|
|
9071
9110
|
};
|
|
9072
9111
|
const SESSION_ID$1 = /^[a-f0-9]{12}$/;
|
|
9073
|
-
const SAFE_ID = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
9112
|
+
const SAFE_ID$1 = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
9074
9113
|
function transportFailureDetail(error) {
|
|
9075
9114
|
if (error instanceof Error && error.name === "AbortError") {
|
|
9076
9115
|
return DESKTOP_STREAM_DETAIL.ended;
|
|
@@ -9117,7 +9156,7 @@ class DesktopStreamRelay {
|
|
|
9117
9156
|
if (!SESSION_ID$1.test(args.sessionId)) {
|
|
9118
9157
|
throw new Error("Invalid session for streaming.");
|
|
9119
9158
|
}
|
|
9120
|
-
if (args.epoch !== void 0 && !SAFE_ID.test(args.epoch)) {
|
|
9159
|
+
if (args.epoch !== void 0 && !SAFE_ID$1.test(args.epoch)) {
|
|
9121
9160
|
throw new Error("Invalid stream epoch.");
|
|
9122
9161
|
}
|
|
9123
9162
|
if (args.afterSeq !== void 0 && (!Number.isInteger(args.afterSeq) || args.afterSeq < 0)) {
|
|
@@ -29452,15 +29491,31 @@ class ApprovalStore {
|
|
|
29452
29491
|
);
|
|
29453
29492
|
}
|
|
29454
29493
|
}
|
|
29494
|
+
function browserWindowForeground(window) {
|
|
29495
|
+
return !window.isDestroyed() && window.isVisible() && window.isFocused();
|
|
29496
|
+
}
|
|
29455
29497
|
function browserChromeOwnsChord(facts) {
|
|
29456
|
-
return facts.logicalFocus && facts.chromeVisible &&
|
|
29498
|
+
return facts.logicalFocus && facts.chromeVisible && browserWindowForeground(facts.window);
|
|
29499
|
+
}
|
|
29500
|
+
function browserPageOwnsChord(facts) {
|
|
29501
|
+
const active = facts.activeTab;
|
|
29502
|
+
return Boolean(
|
|
29503
|
+
active?.presented && browserWindowForeground(facts.window) && (facts.focusedContents() === active.webContentsId || facts.focusedViewTabId === active.tabId)
|
|
29504
|
+
);
|
|
29457
29505
|
}
|
|
29458
29506
|
function runBrowserMenuAction(intent, target2, owner, route) {
|
|
29507
|
+
if (target2 && target2 !== owner) {
|
|
29508
|
+
if (intent === "reload") target2.webContents?.reload();
|
|
29509
|
+
else if (intent === "hard-reload")
|
|
29510
|
+
target2.webContents?.reloadIgnoringCache();
|
|
29511
|
+
else if (intent === "close-tab") target2.close();
|
|
29512
|
+
return;
|
|
29513
|
+
}
|
|
29514
|
+
if (route(intent)) return;
|
|
29459
29515
|
if (!target2) return;
|
|
29460
|
-
if (target2 === owner && route(intent)) return;
|
|
29461
29516
|
if (intent === "reload") target2.webContents?.reload();
|
|
29462
29517
|
else if (intent === "hard-reload") target2.webContents?.reloadIgnoringCache();
|
|
29463
|
-
else target2.close();
|
|
29518
|
+
else if (intent === "close-tab") target2.close();
|
|
29464
29519
|
}
|
|
29465
29520
|
function createBrowserChordRouter(options) {
|
|
29466
29521
|
function dispatch(intent, origin) {
|
|
@@ -33524,7 +33579,26 @@ const enUiChatTags = {
|
|
|
33524
33579
|
"ui.chat.tags.move_undone": "Tag move undone",
|
|
33525
33580
|
"ui.chat.tags.move_title": "Move “{title}”",
|
|
33526
33581
|
"ui.chat.tags.move_description": "Choose a tag to make it primary, or Untagged to remove all tags.",
|
|
33527
|
-
"ui.chat.tags.move_failed": "Tags were not moved. Try again."
|
|
33582
|
+
"ui.chat.tags.move_failed": "Tags were not moved. Try again.",
|
|
33583
|
+
"ui.chat.tags.selection_count": "{count} of 8",
|
|
33584
|
+
"ui.chat.tags.registry_count": "{count} of 32",
|
|
33585
|
+
"ui.chat.tags.create_name": "Create “{name}”",
|
|
33586
|
+
"ui.chat.tags.create_helper": "Saved for all conversations",
|
|
33587
|
+
"ui.chat.tags.selection_limit": "Choose up to 8 tags",
|
|
33588
|
+
"ui.chat.tags.registry_limit": "You can have up to 32 tags",
|
|
33589
|
+
"ui.chat.tags.name_long": "Use 1–24 characters",
|
|
33590
|
+
"ui.chat.tags.name_reserved": "“Untagged” is reserved",
|
|
33591
|
+
"ui.chat.tags.create_failed": "Tag was not created. Try again.",
|
|
33592
|
+
"ui.chat.tags.remove_named": "Remove {name}",
|
|
33593
|
+
"ui.chat.tags.reorder_filtered": "Clear search to reorder tags",
|
|
33594
|
+
"ui.chat.tags.created_name": "Created “{name}”",
|
|
33595
|
+
"ui.chat.tags.selection_status": "{count} selected. Group under {name}.",
|
|
33596
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} other {# conversations}}",
|
|
33597
|
+
"ui.chat.tags.create_pending": "Saving tag…",
|
|
33598
|
+
"ui.chat.tags.remote": "Tags cannot be changed on a remote conversation.",
|
|
33599
|
+
"ui.chat.tags.renamed_name": "Renamed to “{name}”",
|
|
33600
|
+
"ui.chat.tags.staged_added": "Added “{name}” to draft",
|
|
33601
|
+
"ui.chat.tags.registry_changed": "Some tags changed elsewhere. Review your selection."
|
|
33528
33602
|
};
|
|
33529
33603
|
const enUiChatTranscriptCopy = {
|
|
33530
33604
|
"ui.chat.transcript_copy.menu.copy_text": "Copy text",
|
|
@@ -33534,7 +33608,8 @@ const enUiChatTranscriptCopy = {
|
|
|
33534
33608
|
"ui.chat.transcript_copy.toast.copied_selection": "Copied selection",
|
|
33535
33609
|
"ui.chat.transcript_copy.row.your_message": "Your message",
|
|
33536
33610
|
"ui.chat.transcript_copy.row.agent_message": "Agent message",
|
|
33537
|
-
"ui.chat.transcript_copy.selection.copy": "Copy selection"
|
|
33611
|
+
"ui.chat.transcript_copy.selection.copy": "Copy selection",
|
|
33612
|
+
"ui.chat.transcript_copy.selection.toolbar": "Selection actions"
|
|
33538
33613
|
};
|
|
33539
33614
|
const enUiCodeReview = {
|
|
33540
33615
|
"ui.code_review.activity.close": "closed",
|
|
@@ -36212,7 +36287,23 @@ const enUiTeamBridge = {
|
|
|
36212
36287
|
"ui.teamBridge.scope.unknown": "Unknown organization",
|
|
36213
36288
|
"ui.teamBridge.scope.thread_unknown": "This conversation's organization is not available.",
|
|
36214
36289
|
"ui.teamBridge.scope.create_needs_org": "Choose an organization to start a conversation.",
|
|
36215
|
-
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}"
|
|
36290
|
+
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}",
|
|
36291
|
+
"ui.teamBridge.preview.chip": "Preview",
|
|
36292
|
+
"ui.teamBridge.preview.banner": "You’re previewing this channel. Join to see its history and get notifications.",
|
|
36293
|
+
"ui.teamBridge.preview.join": "Join",
|
|
36294
|
+
"ui.teamBridge.preview.join_error": "You could not join this channel. Try again.",
|
|
36295
|
+
"ui.teamBridge.menu.label": "Conversation options",
|
|
36296
|
+
"ui.teamBridge.menu.mute": "Mute conversation",
|
|
36297
|
+
"ui.teamBridge.menu.unmute": "Unmute conversation",
|
|
36298
|
+
"ui.teamBridge.notify.label": "Notification preferences",
|
|
36299
|
+
"ui.teamBridge.notify.all": "All messages",
|
|
36300
|
+
"ui.teamBridge.notify.mention": "Mentions",
|
|
36301
|
+
"ui.teamBridge.notify.mute": "Mute",
|
|
36302
|
+
"ui.teamBridge.notify.muted": "Muted",
|
|
36303
|
+
"ui.teamBridge.notify.error": "Your notification preference was not saved. Try again.",
|
|
36304
|
+
"ui.teamBridge.notify.title": "{conversation} ({organization})",
|
|
36305
|
+
"ui.teamBridge.notify.body": "{sender} sent a message",
|
|
36306
|
+
"ui.teamBridge.notify.body_fallback": "New message"
|
|
36216
36307
|
};
|
|
36217
36308
|
const esUiAgentMessages = {
|
|
36218
36309
|
"ui.agentMessages.dialog.title": "Mensajes de agentes en Radient",
|
|
@@ -36892,7 +36983,26 @@ const esUiChatTags = {
|
|
|
36892
36983
|
"ui.chat.tags.move_undone": "Movimiento de etiquetas deshecho",
|
|
36893
36984
|
"ui.chat.tags.move_title": "Mover «{title}»",
|
|
36894
36985
|
"ui.chat.tags.move_description": "Elige una etiqueta para hacerla principal, o Sin etiqueta para eliminar todas las etiquetas.",
|
|
36895
|
-
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo."
|
|
36986
|
+
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo.",
|
|
36987
|
+
"ui.chat.tags.selection_count": "{count} de 8",
|
|
36988
|
+
"ui.chat.tags.registry_count": "{count} de 32",
|
|
36989
|
+
"ui.chat.tags.create_name": "Crear «{name}»",
|
|
36990
|
+
"ui.chat.tags.create_helper": "Se guarda para todas las conversaciones",
|
|
36991
|
+
"ui.chat.tags.selection_limit": "Elige hasta 8 etiquetas",
|
|
36992
|
+
"ui.chat.tags.registry_limit": "Puedes tener hasta 32 etiquetas",
|
|
36993
|
+
"ui.chat.tags.name_long": "Usa entre 1 y 24 caracteres",
|
|
36994
|
+
"ui.chat.tags.name_reserved": "«Untagged» es un nombre reservado",
|
|
36995
|
+
"ui.chat.tags.create_failed": "No se ha creado la etiqueta. Inténtalo de nuevo.",
|
|
36996
|
+
"ui.chat.tags.remove_named": "Quitar {name}",
|
|
36997
|
+
"ui.chat.tags.reorder_filtered": "Borra la búsqueda para reordenar las etiquetas",
|
|
36998
|
+
"ui.chat.tags.created_name": "Se ha creado «{name}»",
|
|
36999
|
+
"ui.chat.tags.selection_status": "Selección: {count}. Agrupar en {name}.",
|
|
37000
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversación} many {# de conversaciones} other {# conversaciones}}",
|
|
37001
|
+
"ui.chat.tags.create_pending": "Guardando etiqueta…",
|
|
37002
|
+
"ui.chat.tags.remote": "No se pueden cambiar las etiquetas de una conversación remota.",
|
|
37003
|
+
"ui.chat.tags.renamed_name": "Se ha cambiado el nombre a «{name}»",
|
|
37004
|
+
"ui.chat.tags.staged_added": "Se ha añadido «{name}» al borrador",
|
|
37005
|
+
"ui.chat.tags.registry_changed": "Algunas etiquetas han cambiado en otro lugar. Revisa la selección."
|
|
36896
37006
|
};
|
|
36897
37007
|
const esUiCodeReview = {
|
|
36898
37008
|
"ui.code_review.activity.close": "cerraste",
|
|
@@ -40032,7 +40142,26 @@ const frUiChatTags = {
|
|
|
40032
40142
|
"ui.chat.tags.move_undone": "Déplacement des étiquettes annulé",
|
|
40033
40143
|
"ui.chat.tags.move_title": "Déplacer « {title} »",
|
|
40034
40144
|
"ui.chat.tags.move_description": "Choisissez une étiquette principale, ou Sans étiquette pour retirer toutes les étiquettes.",
|
|
40035
|
-
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez."
|
|
40145
|
+
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez.",
|
|
40146
|
+
"ui.chat.tags.selection_count": "{count} sur 8",
|
|
40147
|
+
"ui.chat.tags.registry_count": "{count} sur 32",
|
|
40148
|
+
"ui.chat.tags.create_name": "Créer « {name} »",
|
|
40149
|
+
"ui.chat.tags.create_helper": "Enregistré pour toutes les conversations",
|
|
40150
|
+
"ui.chat.tags.selection_limit": "Choisissez jusqu’à 8 étiquettes",
|
|
40151
|
+
"ui.chat.tags.registry_limit": "Vous pouvez avoir jusqu’à 32 étiquettes",
|
|
40152
|
+
"ui.chat.tags.name_long": "Utilisez de 1 à 24 caractères",
|
|
40153
|
+
"ui.chat.tags.name_reserved": "« Untagged » est un nom réservé",
|
|
40154
|
+
"ui.chat.tags.create_failed": "L’étiquette n’a pas été créée. Réessayez.",
|
|
40155
|
+
"ui.chat.tags.remove_named": "Retirer {name}",
|
|
40156
|
+
"ui.chat.tags.reorder_filtered": "Effacez la recherche pour réordonner les étiquettes",
|
|
40157
|
+
"ui.chat.tags.created_name": "« {name} » a été créée",
|
|
40158
|
+
"ui.chat.tags.selection_status": "{count} sélectionnées. Regrouper sous {name}.",
|
|
40159
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} many {# de conversations} other {# conversations}}",
|
|
40160
|
+
"ui.chat.tags.create_pending": "Enregistrement de l’étiquette…",
|
|
40161
|
+
"ui.chat.tags.remote": "Les étiquettes d’une conversation distante ne peuvent pas être modifiées.",
|
|
40162
|
+
"ui.chat.tags.renamed_name": "Renommée « {name} »",
|
|
40163
|
+
"ui.chat.tags.staged_added": "« {name} » a été ajoutée au brouillon",
|
|
40164
|
+
"ui.chat.tags.registry_changed": "Des étiquettes ont été modifiées ailleurs. Vérifiez votre sélection."
|
|
40036
40165
|
};
|
|
40037
40166
|
const frUiCodeReview = {
|
|
40038
40167
|
"ui.code_review.activity.close": "avez fermé",
|
|
@@ -43259,7 +43388,26 @@ const hiUiChatTags = {
|
|
|
43259
43388
|
"ui.chat.tags.move_undone": "टैग का ले जाना पूर्ववत किया गया",
|
|
43260
43389
|
"ui.chat.tags.move_title": "“{title}” ले जाएँ",
|
|
43261
43390
|
"ui.chat.tags.move_description": "किसी टैग को प्राथमिक बनाने के लिए उसे चुनें, या सभी टैग हटाने के लिए “बिना टैग” चुनें।",
|
|
43262
|
-
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।"
|
|
43391
|
+
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।",
|
|
43392
|
+
"ui.chat.tags.selection_count": "8 में से {count}",
|
|
43393
|
+
"ui.chat.tags.registry_count": "32 में से {count}",
|
|
43394
|
+
"ui.chat.tags.create_name": "“{name}” बनाएँ",
|
|
43395
|
+
"ui.chat.tags.create_helper": "सभी बातचीतों के लिए सहेजा जाता है",
|
|
43396
|
+
"ui.chat.tags.selection_limit": "अधिकतम 8 टैग चुनें",
|
|
43397
|
+
"ui.chat.tags.registry_limit": "आप अधिकतम 32 टैग रख सकते हैं",
|
|
43398
|
+
"ui.chat.tags.name_long": "1–24 अक्षर इस्तेमाल करें",
|
|
43399
|
+
"ui.chat.tags.name_reserved": "“Untagged” नाम आरक्षित है",
|
|
43400
|
+
"ui.chat.tags.create_failed": "टैग नहीं बनाया गया। फिर कोशिश करें।",
|
|
43401
|
+
"ui.chat.tags.remove_named": "{name} हटाएँ",
|
|
43402
|
+
"ui.chat.tags.reorder_filtered": "टैग का क्रम बदलने के लिए खोज साफ़ करें",
|
|
43403
|
+
"ui.chat.tags.created_name": "“{name}” बनाया गया",
|
|
43404
|
+
"ui.chat.tags.selection_status": "{count, plural, =1 {# चुना गया} other {# चुने गए}}। {name} के तहत समूह बनाएँ।",
|
|
43405
|
+
"ui.chat.tags.tag_usage": "{count} बातचीत",
|
|
43406
|
+
"ui.chat.tags.create_pending": "टैग सहेजा जा रहा है…",
|
|
43407
|
+
"ui.chat.tags.remote": "दूरस्थ बातचीत के टैग नहीं बदले जा सकते।",
|
|
43408
|
+
"ui.chat.tags.renamed_name": "नाम बदलकर “{name}” किया गया",
|
|
43409
|
+
"ui.chat.tags.staged_added": "“{name}” मसौदे में जोड़ा गया",
|
|
43410
|
+
"ui.chat.tags.registry_changed": "कुछ टैग कहीं और बदले गए। अपना चयन जाँचें।"
|
|
43263
43411
|
};
|
|
43264
43412
|
const hiUiCodeReview = {
|
|
43265
43413
|
"ui.code_review.activity.close": "बंद किया",
|
|
@@ -46534,7 +46682,26 @@ const ruUiChatTags = {
|
|
|
46534
46682
|
"ui.chat.tags.move_undone": "Перемещение тега отменено",
|
|
46535
46683
|
"ui.chat.tags.move_title": "Переместить «{title}»",
|
|
46536
46684
|
"ui.chat.tags.move_description": "Выберите основной тег или «Без тега», чтобы удалить все теги.",
|
|
46537
|
-
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз."
|
|
46685
|
+
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз.",
|
|
46686
|
+
"ui.chat.tags.selection_count": "{count} из 8",
|
|
46687
|
+
"ui.chat.tags.registry_count": "{count} из 32",
|
|
46688
|
+
"ui.chat.tags.create_name": "Создать «{name}»",
|
|
46689
|
+
"ui.chat.tags.create_helper": "Сохраняется для всех разговоров",
|
|
46690
|
+
"ui.chat.tags.selection_limit": "Выберите не более 8 тегов",
|
|
46691
|
+
"ui.chat.tags.registry_limit": "Можно создать не более 32 тегов",
|
|
46692
|
+
"ui.chat.tags.name_long": "Используйте от 1 до 24 символов",
|
|
46693
|
+
"ui.chat.tags.name_reserved": "Имя «Untagged» зарезервировано",
|
|
46694
|
+
"ui.chat.tags.create_failed": "Тег не создан. Попробуйте ещё раз.",
|
|
46695
|
+
"ui.chat.tags.remove_named": "Убрать {name}",
|
|
46696
|
+
"ui.chat.tags.reorder_filtered": "Очистите поиск, чтобы изменить порядок тегов",
|
|
46697
|
+
"ui.chat.tags.created_name": "Создан тег «{name}»",
|
|
46698
|
+
"ui.chat.tags.selection_status": "Выбрано: {count}. Основной тег: {name}.",
|
|
46699
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# разговор} few {# разговора} many {# разговоров} other {# разговора}}",
|
|
46700
|
+
"ui.chat.tags.create_pending": "Сохранение тега…",
|
|
46701
|
+
"ui.chat.tags.remote": "Нельзя изменить теги удалённого разговора.",
|
|
46702
|
+
"ui.chat.tags.renamed_name": "Новое имя: «{name}»",
|
|
46703
|
+
"ui.chat.tags.staged_added": "Тег «{name}» добавлен в черновик",
|
|
46704
|
+
"ui.chat.tags.registry_changed": "Некоторые теги изменены в другом месте. Проверьте выбор."
|
|
46538
46705
|
};
|
|
46539
46706
|
const ruUiCodeReview = {
|
|
46540
46707
|
"ui.code_review.activity.close": "закрыли",
|
|
@@ -49761,7 +49928,26 @@ const urUiChatTags = {
|
|
|
49761
49928
|
"ui.chat.tags.move_undone": "ٹیگ کی منتقلی واپس کر دی گئی",
|
|
49762
49929
|
"ui.chat.tags.move_title": "“{title}” منتقل کریں",
|
|
49763
49930
|
"ui.chat.tags.move_description": "کسی ٹیگ کو بنیادی بنانے کے لیے اسے منتخب کریں، یا تمام ٹیگز ہٹانے کے لیے “بغیر ٹیگ” منتخب کریں۔",
|
|
49764
|
-
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔"
|
|
49931
|
+
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔",
|
|
49932
|
+
"ui.chat.tags.selection_count": "8 میں سے {count}",
|
|
49933
|
+
"ui.chat.tags.registry_count": "32 میں سے {count}",
|
|
49934
|
+
"ui.chat.tags.create_name": "“{name}” بنائیں",
|
|
49935
|
+
"ui.chat.tags.create_helper": "تمام گفتگوؤں کے لیے محفوظ",
|
|
49936
|
+
"ui.chat.tags.selection_limit": "زیادہ سے زیادہ 8 ٹیگز منتخب کریں",
|
|
49937
|
+
"ui.chat.tags.registry_limit": "آپ زیادہ سے زیادہ 32 ٹیگز رکھ سکتے ہیں",
|
|
49938
|
+
"ui.chat.tags.name_long": "1–24 حروف استعمال کریں",
|
|
49939
|
+
"ui.chat.tags.name_reserved": "“Untagged” نام مخصوص ہے",
|
|
49940
|
+
"ui.chat.tags.create_failed": "ٹیگ نہیں بنا۔ دوبارہ کوشش کریں۔",
|
|
49941
|
+
"ui.chat.tags.remove_named": "{name} ہٹائیں",
|
|
49942
|
+
"ui.chat.tags.reorder_filtered": "ٹیگز کی ترتیب بدلنے کے لیے تلاش صاف کریں",
|
|
49943
|
+
"ui.chat.tags.created_name": "“{name}” بنا دیا گیا",
|
|
49944
|
+
"ui.chat.tags.selection_status": "منتخب: {count}۔ {name} کے گروہ میں رکھیں۔",
|
|
49945
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# گفتگو} other {# گفتگوئیں}}",
|
|
49946
|
+
"ui.chat.tags.create_pending": "ٹیگ محفوظ ہو رہا ہے…",
|
|
49947
|
+
"ui.chat.tags.remote": "ریموٹ گفتگو کے ٹیگز تبدیل نہیں کیے جا سکتے۔",
|
|
49948
|
+
"ui.chat.tags.renamed_name": "نام بدل کر “{name}” کر دیا گیا",
|
|
49949
|
+
"ui.chat.tags.staged_added": "“{name}” مسودے میں شامل کر دیا گیا",
|
|
49950
|
+
"ui.chat.tags.registry_changed": "کچھ ٹیگز کہیں اور تبدیل ہو گئے ہیں۔ اپنے انتخاب کا جائزہ لیں۔"
|
|
49765
49951
|
};
|
|
49766
49952
|
const urUiCodeReview = {
|
|
49767
49953
|
"ui.code_review.activity.close": "بند کیا",
|
|
@@ -53056,7 +53242,26 @@ const viUiChatTags = {
|
|
|
53056
53242
|
"ui.chat.tags.move_undone": "Đã hoàn tác thao tác chuyển nhãn",
|
|
53057
53243
|
"ui.chat.tags.move_title": "Chuyển “{title}”",
|
|
53058
53244
|
"ui.chat.tags.move_description": "Chọn một nhãn làm nhãn chính, hoặc chọn Chưa gắn nhãn để gỡ hết nhãn.",
|
|
53059
|
-
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại."
|
|
53245
|
+
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại.",
|
|
53246
|
+
"ui.chat.tags.selection_count": "{count} trên 8",
|
|
53247
|
+
"ui.chat.tags.registry_count": "{count} trên 32",
|
|
53248
|
+
"ui.chat.tags.create_name": "Tạo “{name}”",
|
|
53249
|
+
"ui.chat.tags.create_helper": "Được lưu cho mọi cuộc trò chuyện",
|
|
53250
|
+
"ui.chat.tags.selection_limit": "Chọn tối đa 8 nhãn",
|
|
53251
|
+
"ui.chat.tags.registry_limit": "Bạn có thể có tối đa 32 nhãn",
|
|
53252
|
+
"ui.chat.tags.name_long": "Dùng từ 1 đến 24 ký tự",
|
|
53253
|
+
"ui.chat.tags.name_reserved": "“Untagged” là tên dành riêng",
|
|
53254
|
+
"ui.chat.tags.create_failed": "Chưa tạo được nhãn. Hãy thử lại.",
|
|
53255
|
+
"ui.chat.tags.remove_named": "Bỏ {name}",
|
|
53256
|
+
"ui.chat.tags.reorder_filtered": "Xóa tìm kiếm để sắp xếp lại nhãn",
|
|
53257
|
+
"ui.chat.tags.created_name": "Đã tạo “{name}”",
|
|
53258
|
+
"ui.chat.tags.selection_status": "Đã chọn {count}. Nhóm vào {name}.",
|
|
53259
|
+
"ui.chat.tags.tag_usage": "{count} cuộc trò chuyện",
|
|
53260
|
+
"ui.chat.tags.create_pending": "Đang lưu nhãn…",
|
|
53261
|
+
"ui.chat.tags.remote": "Không thể thay đổi nhãn của cuộc trò chuyện từ xa.",
|
|
53262
|
+
"ui.chat.tags.renamed_name": "Đã đổi tên thành “{name}”",
|
|
53263
|
+
"ui.chat.tags.staged_added": "Đã thêm “{name}” vào bản nháp",
|
|
53264
|
+
"ui.chat.tags.registry_changed": "Một số nhãn đã thay đổi ở nơi khác. Hãy kiểm tra lựa chọn."
|
|
53060
53265
|
};
|
|
53061
53266
|
const viUiCodeReview = {
|
|
53062
53267
|
"ui.code_review.activity.close": "đã đóng",
|
|
@@ -56006,7 +56211,26 @@ const zhCNUiChatTags = {
|
|
|
56006
56211
|
"ui.chat.tags.move_undone": "已撤销标签移动",
|
|
56007
56212
|
"ui.chat.tags.move_title": "移动“{title}”",
|
|
56008
56213
|
"ui.chat.tags.move_description": "选择一个标签将其设为主标签,或选择“无标签”以移除所有标签。",
|
|
56009
|
-
"ui.chat.tags.move_failed": "标签未移动。请重试。"
|
|
56214
|
+
"ui.chat.tags.move_failed": "标签未移动。请重试。",
|
|
56215
|
+
"ui.chat.tags.selection_count": "已选 {count}/8",
|
|
56216
|
+
"ui.chat.tags.registry_count": "{count}/32",
|
|
56217
|
+
"ui.chat.tags.create_name": "创建“{name}”",
|
|
56218
|
+
"ui.chat.tags.create_helper": "保存后可用于所有对话",
|
|
56219
|
+
"ui.chat.tags.selection_limit": "最多选择 8 个标签",
|
|
56220
|
+
"ui.chat.tags.registry_limit": "最多可有 32 个标签",
|
|
56221
|
+
"ui.chat.tags.name_long": "请使用 1–24 个字符",
|
|
56222
|
+
"ui.chat.tags.name_reserved": "“Untagged”是保留名称",
|
|
56223
|
+
"ui.chat.tags.create_failed": "未能创建标签。请重试。",
|
|
56224
|
+
"ui.chat.tags.remove_named": "移除{name}",
|
|
56225
|
+
"ui.chat.tags.reorder_filtered": "清空搜索以调整标签顺序",
|
|
56226
|
+
"ui.chat.tags.created_name": "已创建“{name}”",
|
|
56227
|
+
"ui.chat.tags.selection_status": "已选择 {count} 个,归入{name}。",
|
|
56228
|
+
"ui.chat.tags.tag_usage": "{count} 个对话",
|
|
56229
|
+
"ui.chat.tags.create_pending": "正在保存标签…",
|
|
56230
|
+
"ui.chat.tags.remote": "无法更改远程对话的标签。",
|
|
56231
|
+
"ui.chat.tags.renamed_name": "已重命名为“{name}”",
|
|
56232
|
+
"ui.chat.tags.staged_added": "已将“{name}”加入草稿",
|
|
56233
|
+
"ui.chat.tags.registry_changed": "部分标签已在别处更改。请检查所选标签。"
|
|
56010
56234
|
};
|
|
56011
56235
|
const zhCNUiCodeReview = {
|
|
56012
56236
|
"ui.code_review.activity.close": "已关闭",
|
|
@@ -62518,6 +62742,15 @@ class BrowserHost {
|
|
|
62518
62742
|
}
|
|
62519
62743
|
/** Main owns this short-lived UI focus fact; it conveys no page capability. */
|
|
62520
62744
|
chordFocus = false;
|
|
62745
|
+
/**
|
|
62746
|
+
* The tab whose native view last reported focus. Tracked from each view's own
|
|
62747
|
+
* `focus`/`blur` events because `webContents.getFocusedWebContents()` can
|
|
62748
|
+
* answer null while a `WebContentsView` holds focus (measured on Electron
|
|
62749
|
+
* 44.3.0 in a window that is not itself activated). Like `chordFocus`, this
|
|
62750
|
+
* is an input-ownership fact and carries no page capability; `ownsPage`
|
|
62751
|
+
* refuses it unless the tab is the active, presented one.
|
|
62752
|
+
*/
|
|
62753
|
+
focusedPageTabId = null;
|
|
62521
62754
|
onChordFocusChanged;
|
|
62522
62755
|
/** An explicit tab id fences queued chrome intents: a switch between key
|
|
62523
62756
|
* delivery and IPC must never search/zoom the newly active tab instead. */
|
|
@@ -62540,6 +62773,16 @@ class BrowserHost {
|
|
|
62540
62773
|
this.chordFocus = focused;
|
|
62541
62774
|
this.onChordFocusChanged?.(focused);
|
|
62542
62775
|
}
|
|
62776
|
+
/** One view gained or lost native focus. Only the id that lost it may clear
|
|
62777
|
+
* the fact: a departing view's blur must not erase a successor's focus. */
|
|
62778
|
+
setPageFocused(tabId, focused) {
|
|
62779
|
+
if (focused) this.focusedPageTabId = tabId;
|
|
62780
|
+
else if (this.focusedPageTabId === tabId) this.focusedPageTabId = null;
|
|
62781
|
+
}
|
|
62782
|
+
/** The window's own renderer gained focus (the user clicked chrome/chat). */
|
|
62783
|
+
clearPageFocus() {
|
|
62784
|
+
this.focusedPageTabId = null;
|
|
62785
|
+
}
|
|
62543
62786
|
/** Only user URLs survive a close, never a capability, page state or nonce.
|
|
62544
62787
|
* Conversation attribution is retained only to find the appropriate scope. */
|
|
62545
62788
|
closedUserTabs = [];
|
|
@@ -62558,6 +62801,7 @@ class BrowserHost {
|
|
|
62558
62801
|
clearChordState() {
|
|
62559
62802
|
this.pageControls.clear();
|
|
62560
62803
|
this.setChordFocus(false);
|
|
62804
|
+
this.clearPageFocus();
|
|
62561
62805
|
this.closedUserTabs = [];
|
|
62562
62806
|
}
|
|
62563
62807
|
/**
|
|
@@ -62948,12 +63192,14 @@ class BrowserHost {
|
|
|
62948
63192
|
* area and reports it, and main applies it to the active tab only. */
|
|
62949
63193
|
setContentRect(rect) {
|
|
62950
63194
|
this.registry.setContentRect(rect);
|
|
63195
|
+
if (rect === null) this.clearPageFocus();
|
|
62951
63196
|
return this.chromeState();
|
|
62952
63197
|
}
|
|
62953
63198
|
/** Full-window overlays hide the view: a native view paints above all DOM, so
|
|
62954
63199
|
* an overlay is invisible unless the view goes away (design 11.3). */
|
|
62955
63200
|
setViewVisible(visible) {
|
|
62956
63201
|
this.registry.setViewVisible(visible);
|
|
63202
|
+
if (!visible) this.clearPageFocus();
|
|
62957
63203
|
return this.chromeState();
|
|
62958
63204
|
}
|
|
62959
63205
|
/** Hand a user tab to a session, minting the capability. The RENDERER never
|
|
@@ -66217,6 +66463,8 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66217
66463
|
return view;
|
|
66218
66464
|
}, wireView = function(view, tabId) {
|
|
66219
66465
|
const contents = view.webContents;
|
|
66466
|
+
contents.on("focus", () => host.setPageFocused(tabId, true));
|
|
66467
|
+
contents.on("blur", () => host.setPageFocused(tabId, false));
|
|
66220
66468
|
const popupChildren = /* @__PURE__ */ new Set();
|
|
66221
66469
|
contents.setWindowOpenHandler((details) => {
|
|
66222
66470
|
const decision = decidePopup(
|
|
@@ -66378,6 +66626,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66378
66626
|
if (token) approvals.forgetDocument(token);
|
|
66379
66627
|
registry.forget(tabId);
|
|
66380
66628
|
}
|
|
66629
|
+
host.setPageFocused(tabId, false);
|
|
66381
66630
|
host.clearLoadFailure(tabId);
|
|
66382
66631
|
releaseTab(tabId, contents.id);
|
|
66383
66632
|
});
|
|
@@ -66653,9 +66902,18 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66653
66902
|
ownsChrome,
|
|
66654
66903
|
ownsPage: () => {
|
|
66655
66904
|
const record = registry.activeTab;
|
|
66656
|
-
return
|
|
66657
|
-
record
|
|
66658
|
-
|
|
66905
|
+
return browserPageOwnsChord({
|
|
66906
|
+
activeTab: record ? {
|
|
66907
|
+
tabId: record.tabId,
|
|
66908
|
+
webContentsId: record.view.webContents.id,
|
|
66909
|
+
presented: record.presented
|
|
66910
|
+
} : null,
|
|
66911
|
+
// Read lazily after the window/presented floor: a startup or test host
|
|
66912
|
+
// may carry a webContents slice without the getter.
|
|
66913
|
+
focusedContents: () => electron.webContents.getFocusedWebContents()?.id ?? null,
|
|
66914
|
+
focusedViewTabId: host.focusedPageTabId,
|
|
66915
|
+
window: options.window
|
|
66916
|
+
});
|
|
66659
66917
|
},
|
|
66660
66918
|
reload: (hard) => {
|
|
66661
66919
|
host.reloadActive(hard);
|
|
@@ -66687,6 +66945,9 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66687
66945
|
const resetChordFocus = () => {
|
|
66688
66946
|
host.setChordFocus(false);
|
|
66689
66947
|
};
|
|
66948
|
+
const resetPageFocus = () => {
|
|
66949
|
+
host.clearPageFocus();
|
|
66950
|
+
};
|
|
66690
66951
|
const resetMenuShortcutSuppression = () => {
|
|
66691
66952
|
if (!options.window.webContents.isDestroyed())
|
|
66692
66953
|
options.window.webContents.setIgnoreMenuShortcuts(false);
|
|
@@ -66695,6 +66956,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66695
66956
|
if (!focused) resetMenuShortcutSuppression();
|
|
66696
66957
|
};
|
|
66697
66958
|
options.window.webContents.on("before-input-event", onChromeInput);
|
|
66959
|
+
options.window.webContents.on("focus", resetPageFocus);
|
|
66698
66960
|
options.window.on("blur", resetMenuShortcutSuppression);
|
|
66699
66961
|
options.window.on("closed", resetChordFocus);
|
|
66700
66962
|
const resetOnNavigation = (details) => {
|
|
@@ -66708,6 +66970,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66708
66970
|
"before-input-event",
|
|
66709
66971
|
onChromeInput
|
|
66710
66972
|
);
|
|
66973
|
+
options.window.webContents.removeListener("focus", resetPageFocus);
|
|
66711
66974
|
options.window.removeListener("blur", resetMenuShortcutSuppression);
|
|
66712
66975
|
options.window.removeListener("closed", resetChordFocus);
|
|
66713
66976
|
options.window.webContents.removeListener(
|
|
@@ -66999,7 +67262,7 @@ function isAdmittedSender(event, admitted) {
|
|
|
66999
67262
|
(candidate) => candidate.window !== null && !candidate.window.isDestroyed() && event.sender === candidate.window.webContents && event.senderFrame === candidate.window.webContents.mainFrame && trustedDesktopFrame(event.senderFrame.url, candidate.url)
|
|
67000
67263
|
);
|
|
67001
67264
|
}
|
|
67002
|
-
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2) {
|
|
67265
|
+
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2, teamBridgeNotifier) {
|
|
67003
67266
|
const opened = /* @__PURE__ */ new Map();
|
|
67004
67267
|
function authorize(event) {
|
|
67005
67268
|
const admitted = [
|
|
@@ -67063,6 +67326,16 @@ function registerDesktopIPC(window, expectedUrl, request, streams, media, notifi
|
|
|
67063
67326
|
noteLeftSession?.(args.sessionId);
|
|
67064
67327
|
});
|
|
67065
67328
|
}
|
|
67329
|
+
if (teamBridgeNotifier) {
|
|
67330
|
+
electron.ipcMain.handle("team-bridge:notify", (event, input) => {
|
|
67331
|
+
authorize(event);
|
|
67332
|
+
return teamBridgeNotifier.notify(input);
|
|
67333
|
+
});
|
|
67334
|
+
electron.ipcMain.handle("team-bridge:pending-open", (event) => {
|
|
67335
|
+
authorize(event);
|
|
67336
|
+
return teamBridgeNotifier.takePendingOpen();
|
|
67337
|
+
});
|
|
67338
|
+
}
|
|
67066
67339
|
if (media) {
|
|
67067
67340
|
electron.ipcMain.handle("desktop-media", (event, input, bytes) => {
|
|
67068
67341
|
authorize(event);
|
|
@@ -69020,6 +69293,227 @@ function installSupplementProtocol(fetchDocument, log2) {
|
|
|
69020
69293
|
});
|
|
69021
69294
|
});
|
|
69022
69295
|
}
|
|
69296
|
+
const TEAM_BRIDGE_NOTIFY_MAX_TITLE = 320;
|
|
69297
|
+
const TEAM_BRIDGE_NOTIFY_MAX_BODY = 200;
|
|
69298
|
+
const MAX_SEQ = Number.MAX_SAFE_INTEGER;
|
|
69299
|
+
const SAFE_ID = /^[A-Za-z0-9_.:-]{1,128}$/;
|
|
69300
|
+
function hasUnsafeText(value) {
|
|
69301
|
+
for (const character of value) {
|
|
69302
|
+
const code = character.codePointAt(0) ?? 0;
|
|
69303
|
+
if (character === "<" || character === ">" || code < 32 || code === 127) {
|
|
69304
|
+
return true;
|
|
69305
|
+
}
|
|
69306
|
+
}
|
|
69307
|
+
return false;
|
|
69308
|
+
}
|
|
69309
|
+
function cleanId(value) {
|
|
69310
|
+
return typeof value === "string" && SAFE_ID.test(value) ? value : null;
|
|
69311
|
+
}
|
|
69312
|
+
function cleanText(value, max) {
|
|
69313
|
+
if (typeof value !== "string") return null;
|
|
69314
|
+
const trimmed = value.trim();
|
|
69315
|
+
if (trimmed.length === 0 || trimmed.length > max) return null;
|
|
69316
|
+
if (hasUnsafeText(trimmed)) return null;
|
|
69317
|
+
return trimmed;
|
|
69318
|
+
}
|
|
69319
|
+
function parseTeamBridgeNotifyRequest(value) {
|
|
69320
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69321
|
+
return null;
|
|
69322
|
+
}
|
|
69323
|
+
const input = value;
|
|
69324
|
+
const conversationId = cleanId(input.conversationId);
|
|
69325
|
+
const tenantId = cleanId(input.tenantId);
|
|
69326
|
+
const title = cleanText(input.title, TEAM_BRIDGE_NOTIFY_MAX_TITLE);
|
|
69327
|
+
const body = cleanText(input.body, TEAM_BRIDGE_NOTIFY_MAX_BODY);
|
|
69328
|
+
const seq2 = input.seq;
|
|
69329
|
+
if (conversationId === null || tenantId === null || title === null || body === null || typeof seq2 !== "number" || !Number.isSafeInteger(seq2) || seq2 < 0 || seq2 > MAX_SEQ) {
|
|
69330
|
+
return null;
|
|
69331
|
+
}
|
|
69332
|
+
return { conversationId, tenantId, title, body, seq: seq2 };
|
|
69333
|
+
}
|
|
69334
|
+
function teamBridgeWindowIsQuiet(window) {
|
|
69335
|
+
if (!window) return false;
|
|
69336
|
+
return !window.isDestroyed() && window.isVisible() && !window.isMinimized() && window.isFocused();
|
|
69337
|
+
}
|
|
69338
|
+
class TeamBridgeNotifier {
|
|
69339
|
+
constructor(options) {
|
|
69340
|
+
this.options = options;
|
|
69341
|
+
this.createBanner = options.createBanner ?? ((bannerOptions) => new electron.Notification(bannerOptions));
|
|
69342
|
+
this.canNotify = options.canNotify ?? (() => electron.Notification.isSupported());
|
|
69343
|
+
}
|
|
69344
|
+
/** The live banner per conversation, so a new seq REPLACES it. */
|
|
69345
|
+
banners = /* @__PURE__ */ new Map();
|
|
69346
|
+
/** The banners this process must keep reachable for their clicks to fire. */
|
|
69347
|
+
lifetime = new NotificationLifetime();
|
|
69348
|
+
pendingOpen = null;
|
|
69349
|
+
createBanner;
|
|
69350
|
+
canNotify;
|
|
69351
|
+
/**
|
|
69352
|
+
* Validate, dedupe and deliver one banner.
|
|
69353
|
+
*
|
|
69354
|
+
* REFUSAL IS AN ERROR, not a quiet `false`: a malformed payload is a bug in
|
|
69355
|
+
* the caller, and the IPC handler should reject rather than let the renderer
|
|
69356
|
+
* believe it raised something. A well-formed payload that is suppressed
|
|
69357
|
+
* (quiet, muted by focus, duplicate, unsupported) answers `shown: false`.
|
|
69358
|
+
*/
|
|
69359
|
+
notify(input) {
|
|
69360
|
+
const request = parseTeamBridgeNotifyRequest(input);
|
|
69361
|
+
if (request === null) {
|
|
69362
|
+
throw new Error("Invalid Team Bridge notification payload.");
|
|
69363
|
+
}
|
|
69364
|
+
if (this.options.show === "never") return { shown: false };
|
|
69365
|
+
if (!this.canNotify()) return { shown: false };
|
|
69366
|
+
if (teamBridgeWindowIsQuiet(this.options.window())) {
|
|
69367
|
+
return { shown: false };
|
|
69368
|
+
}
|
|
69369
|
+
const previous = this.options.store.notifiedSeq(request.conversationId);
|
|
69370
|
+
if (previous !== void 0 && request.seq <= previous) {
|
|
69371
|
+
return { shown: false };
|
|
69372
|
+
}
|
|
69373
|
+
this.replace(request.conversationId);
|
|
69374
|
+
const notification = this.createBanner({
|
|
69375
|
+
title: request.title,
|
|
69376
|
+
body: request.body,
|
|
69377
|
+
silent: false,
|
|
69378
|
+
...this.options.icon ? { icon: this.options.icon } : {}
|
|
69379
|
+
});
|
|
69380
|
+
this.lifetime.retain(notification, () => {
|
|
69381
|
+
this.banners.delete(request.conversationId);
|
|
69382
|
+
this.open(request);
|
|
69383
|
+
});
|
|
69384
|
+
notification.once("close", () => {
|
|
69385
|
+
if (this.banners.get(request.conversationId) === notification) {
|
|
69386
|
+
this.banners.delete(request.conversationId);
|
|
69387
|
+
}
|
|
69388
|
+
});
|
|
69389
|
+
notification.show();
|
|
69390
|
+
this.banners.set(request.conversationId, notification);
|
|
69391
|
+
this.options.store.record(request.conversationId, request.seq);
|
|
69392
|
+
return { shown: true };
|
|
69393
|
+
}
|
|
69394
|
+
/**
|
|
69395
|
+
* The target a click parked for the renderer.
|
|
69396
|
+
*
|
|
69397
|
+
* Consumed exactly once: the renderer asks for it on mount and on every
|
|
69398
|
+
* `team-bridge:open` signal, and a later pull gets `null` rather than
|
|
69399
|
+
* replaying a conversation the user has already seen. The value was built
|
|
69400
|
+
* from an already-validated notification payload, so this read does not
|
|
69401
|
+
* re-parse ids.
|
|
69402
|
+
*/
|
|
69403
|
+
takePendingOpen() {
|
|
69404
|
+
const pending = this.pendingOpen;
|
|
69405
|
+
this.pendingOpen = null;
|
|
69406
|
+
return pending;
|
|
69407
|
+
}
|
|
69408
|
+
replace(conversationId) {
|
|
69409
|
+
const previous = this.banners.get(conversationId);
|
|
69410
|
+
if (!previous) return;
|
|
69411
|
+
this.banners.delete(conversationId);
|
|
69412
|
+
previous.close?.();
|
|
69413
|
+
}
|
|
69414
|
+
open(request) {
|
|
69415
|
+
const target2 = {
|
|
69416
|
+
conversationId: request.conversationId,
|
|
69417
|
+
tenantId: request.tenantId
|
|
69418
|
+
};
|
|
69419
|
+
this.pendingOpen = target2;
|
|
69420
|
+
const window = this.options.window();
|
|
69421
|
+
if (window && !window.isDestroyed()) {
|
|
69422
|
+
this.options.host.signalOpen();
|
|
69423
|
+
this.options.present?.(window);
|
|
69424
|
+
return;
|
|
69425
|
+
}
|
|
69426
|
+
this.options.host.reopen();
|
|
69427
|
+
}
|
|
69428
|
+
}
|
|
69429
|
+
const TEAM_BRIDGE_NOTIFY_CURSOR_BOUND = 2048;
|
|
69430
|
+
const VERSION = 1;
|
|
69431
|
+
function isCursor(value) {
|
|
69432
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
69433
|
+
}
|
|
69434
|
+
class TeamBridgeNotifyStore {
|
|
69435
|
+
constructor(file, onError = () => void 0) {
|
|
69436
|
+
this.file = file;
|
|
69437
|
+
this.onError = onError;
|
|
69438
|
+
this.load();
|
|
69439
|
+
}
|
|
69440
|
+
cursors = /* @__PURE__ */ new Map();
|
|
69441
|
+
/** The newest seq a banner was raised for, or `undefined`. */
|
|
69442
|
+
notifiedSeq(conversationId) {
|
|
69443
|
+
return this.cursors.get(conversationId);
|
|
69444
|
+
}
|
|
69445
|
+
/**
|
|
69446
|
+
* Remember that this conversation was notified at `seq`.
|
|
69447
|
+
*
|
|
69448
|
+
* Only advances: a late poll whose seq is older than the recorded one must
|
|
69449
|
+
* not move the cursor backwards and re-open the door to a duplicate banner.
|
|
69450
|
+
* Touching an existing key moves it to the newest position so the bound
|
|
69451
|
+
* evicts by usefulness rather than alphabetically.
|
|
69452
|
+
*/
|
|
69453
|
+
record(conversationId, seq2) {
|
|
69454
|
+
if (!isCursor(seq2)) return;
|
|
69455
|
+
const previous = this.cursors.get(conversationId);
|
|
69456
|
+
if (previous !== void 0 && seq2 <= previous) return;
|
|
69457
|
+
this.cursors.delete(conversationId);
|
|
69458
|
+
this.cursors.set(conversationId, seq2);
|
|
69459
|
+
this.trim();
|
|
69460
|
+
this.persist();
|
|
69461
|
+
}
|
|
69462
|
+
/**
|
|
69463
|
+
* Enforce the bound on BOTH paths: `record` while a run is live and `load` on
|
|
69464
|
+
* a file written by an older or hand-edited build. A bound enforced only on
|
|
69465
|
+
* the write path is a promise about files this process wrote itself, which is
|
|
69466
|
+
* not the file it has just read.
|
|
69467
|
+
*/
|
|
69468
|
+
trim() {
|
|
69469
|
+
while (this.cursors.size > TEAM_BRIDGE_NOTIFY_CURSOR_BOUND) {
|
|
69470
|
+
const oldest = this.cursors.keys().next();
|
|
69471
|
+
if (oldest.done) break;
|
|
69472
|
+
this.cursors.delete(oldest.value);
|
|
69473
|
+
}
|
|
69474
|
+
}
|
|
69475
|
+
load() {
|
|
69476
|
+
let raw;
|
|
69477
|
+
try {
|
|
69478
|
+
raw = fs.readFileSync(this.file, "utf8");
|
|
69479
|
+
} catch {
|
|
69480
|
+
return;
|
|
69481
|
+
}
|
|
69482
|
+
try {
|
|
69483
|
+
const parsed = JSON.parse(raw);
|
|
69484
|
+
if (parsed === null || typeof parsed !== "object" || parsed.version !== VERSION) {
|
|
69485
|
+
return;
|
|
69486
|
+
}
|
|
69487
|
+
const cursors = parsed.cursors;
|
|
69488
|
+
if (cursors === null || typeof cursors !== "object") return;
|
|
69489
|
+
for (const [conversationId, seq2] of Object.entries(
|
|
69490
|
+
cursors
|
|
69491
|
+
)) {
|
|
69492
|
+
if (isCursor(seq2)) this.cursors.set(conversationId, seq2);
|
|
69493
|
+
}
|
|
69494
|
+
this.trim();
|
|
69495
|
+
} catch (error) {
|
|
69496
|
+
this.onError("team-bridge notification cursor file is unreadable", error);
|
|
69497
|
+
}
|
|
69498
|
+
}
|
|
69499
|
+
persist() {
|
|
69500
|
+
const payload = {
|
|
69501
|
+
version: VERSION,
|
|
69502
|
+
cursors: Object.fromEntries(this.cursors)
|
|
69503
|
+
};
|
|
69504
|
+
try {
|
|
69505
|
+
fs.mkdirSync(path$1.dirname(this.file), { recursive: true, mode: 448 });
|
|
69506
|
+
const temporary = `${this.file}.${process.pid}.tmp`;
|
|
69507
|
+
fs.writeFileSync(temporary, JSON.stringify(payload), { mode: 384 });
|
|
69508
|
+
fs.renameSync(temporary, this.file);
|
|
69509
|
+
} catch (error) {
|
|
69510
|
+
this.onError(
|
|
69511
|
+
"team-bridge notification cursor could not be written",
|
|
69512
|
+
error
|
|
69513
|
+
);
|
|
69514
|
+
}
|
|
69515
|
+
}
|
|
69516
|
+
}
|
|
69023
69517
|
function titlebarOptions(platform, chrome) {
|
|
69024
69518
|
if (platform === "darwin") {
|
|
69025
69519
|
return { titleBarStyle: "hidden" };
|
|
@@ -77493,6 +77987,25 @@ function createApplicationMenu() {
|
|
|
77493
77987
|
{
|
|
77494
77988
|
label: "View",
|
|
77495
77989
|
submenu: [
|
|
77990
|
+
{
|
|
77991
|
+
id: "app-new-tab",
|
|
77992
|
+
label: "New Browser Tab",
|
|
77993
|
+
accelerator: "CmdOrCtrl+T",
|
|
77994
|
+
/*
|
|
77995
|
+
* THE NATIVE ACCELERATOR ROUTE FOR CMD+T, which had no menu item at all.
|
|
77996
|
+
* The browser owns the command through the same predicate as Reload
|
|
77997
|
+
* (`ownsPage` for a focused driven page, `ownsChrome` for browser chrome);
|
|
77998
|
+
* outside the browser this is deliberately a no-op, never a window close.
|
|
77999
|
+
* When the chrome's own `before-input-event` already claimed the press it
|
|
78000
|
+
* prevents this accelerator, so rapid/legit presses stay exactly once.
|
|
78001
|
+
*/
|
|
78002
|
+
click: (_item, target2) => runBrowserMenuAction(
|
|
78003
|
+
"new-tab",
|
|
78004
|
+
target2,
|
|
78005
|
+
mainWindow,
|
|
78006
|
+
routeBrowserMenu
|
|
78007
|
+
)
|
|
78008
|
+
},
|
|
77496
78009
|
{
|
|
77497
78010
|
id: "app-reload",
|
|
77498
78011
|
label: "Reload",
|
|
@@ -78336,6 +78849,28 @@ electron.app.whenReady().then(async () => {
|
|
|
78336
78849
|
// line is what tells that trigger apart from the other four.
|
|
78337
78850
|
reportRaise
|
|
78338
78851
|
);
|
|
78852
|
+
const teamBridgeNotifier = new TeamBridgeNotifier({
|
|
78853
|
+
window: () => mainWindow,
|
|
78854
|
+
show: windowLaunch.show,
|
|
78855
|
+
icon: image,
|
|
78856
|
+
store: new TeamBridgeNotifyStore(
|
|
78857
|
+
path$1.join(electron.app.getPath("userData"), "team-bridge-notifications.json"),
|
|
78858
|
+
(message, error) => logger.warn(`${message}: ${String(error)}`, LogFileType.BACKEND)
|
|
78859
|
+
),
|
|
78860
|
+
host: {
|
|
78861
|
+
signalOpen: () => {
|
|
78862
|
+
const window = mainWindow;
|
|
78863
|
+
if (window && !window.isDestroyed()) {
|
|
78864
|
+
window.webContents.send("team-bridge:open");
|
|
78865
|
+
}
|
|
78866
|
+
},
|
|
78867
|
+
reopen: () => electron.app.emit("activate")
|
|
78868
|
+
},
|
|
78869
|
+
present: (window) => raiseWindow(window, windowLaunch.show, {
|
|
78870
|
+
trigger: "banner-click",
|
|
78871
|
+
report: reportRaise
|
|
78872
|
+
})
|
|
78873
|
+
});
|
|
78339
78874
|
backendService.onBackendReady(() => {
|
|
78340
78875
|
void desktopNotifier.refreshNotificationContract();
|
|
78341
78876
|
void backendService.getDesktopFeedRelay().start();
|
|
@@ -78608,7 +79143,8 @@ electron.app.whenReady().then(async () => {
|
|
|
78608
79143
|
* same instance `createWindow` gave the navigation guard: the arm channel
|
|
78609
79144
|
* and the guard are two halves of one decision and must share one list.
|
|
78610
79145
|
*/
|
|
78611
|
-
supplementMounts
|
|
79146
|
+
supplementMounts,
|
|
79147
|
+
teamBridgeNotifier
|
|
78612
79148
|
);
|
|
78613
79149
|
if (devDriverArming.armed && devDriverArming.outDir) {
|
|
78614
79150
|
registerDevDriverIPC({
|