local-operator-ui 0.31.26 → 0.31.28
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 +383 -42
- package/out/preload/index.js +37 -0
- package/out/renderer/assets/{_basePickBy-D0wlCvva.js → _basePickBy-D16oopNi.js} +1 -1
- package/out/renderer/assets/{_baseUniq-DPa_8DrG.js → _baseUniq-BYKYfwtj.js} +1 -1
- package/out/renderer/assets/{agent-details-page-CrARDEtK.js → agent-details-page-CpwkLhdq.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-tj8FYJ7M.js → agent-hub-page-BYeba0zC.js} +3 -3
- package/out/renderer/assets/agents-page-BQdR1fgV.js +7 -0
- package/out/renderer/assets/arc-BYg3WIzZ.js +1 -0
- package/out/renderer/assets/architectureDiagram-IEHRJDOE-np6HwkQz.js +36 -0
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-D0DwK5Ey.js → blockDiagram-JOT3LUYC-CaR7YwVl.js} +2 -2
- package/out/renderer/assets/{book-open-DeQc_I6g.js → book-open--g1VlVMp.js} +1 -1
- package/out/renderer/assets/browser-page-BPwZPQY2.js +1 -0
- package/out/renderer/assets/browser-webauthn-prompt-Bsk0eXNZ.js +1 -0
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-CubzqfYr.js → c4Diagram-VJAJSXHY-DqBT3rl5.js} +4 -4
- package/out/renderer/assets/channel-mWTr8anL.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-AysrzODh.js → chunk-4BMEZGHF-B7-MzFPi.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-DfDo-OSy.js → chunk-A2AXSNBT-B9IqNrNg.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-5xgHbFtp.js → chunk-AEK57VVT-DFzBJNd9.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-pYCMpQiN.js → chunk-D6G4REZN-DW-XzsAv.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-C5bWxzka.js → chunk-RZ5BOZE2-C7el6yre.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-B4wB3iEG.js → chunk-XZIHB7SX-BGYrq1Wn.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-DsNAZ0y6.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-DsNAZ0y6.js +1 -0
- package/out/renderer/assets/clone-48M_nlg0.js +1 -0
- package/out/renderer/assets/{console-mirror-45f9-7QH.js → console-mirror-ffbsozOd.js} +1 -1
- package/out/renderer/assets/{consoleCapture-GiahzrSM.js → consoleCapture-CiApa6fi.js} +1 -1
- package/out/renderer/assets/conversation-input-sync-CIGg7Rga.css +1 -0
- package/out/renderer/assets/conversation-input-sync-DQUYkOfh.js +911 -0
- package/out/renderer/assets/dagre-OKDRZEBW-BVScRDvj.js +4 -0
- package/out/renderer/assets/diagram-SSKATNLV-B0iQ6YY1.js +43 -0
- package/out/renderer/assets/diagram-VNBRO52H-Co6YPtUT.js +24 -0
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-Cpuc-IVT.js → erDiagram-Q7BY3M3F-C9XIuSQl.js} +2 -2
- package/out/renderer/assets/error-boundary-DH4MhqhL.js +126 -0
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-CsO4ubSn.js → flowDiagram-4HSFHLVR-QTHrGPk1.js} +2 -2
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-LYPPAOmY.js → ganttDiagram-APWFNJXF-qC1VnBIz.js} +4 -4
- package/out/renderer/assets/gitGraphDiagram-7IBYFJ6S-D7UGP8uH.js +65 -0
- package/out/renderer/assets/{graph-uBeiISg2.js → graph-BIUuz2bp.js} +1 -1
- package/out/renderer/assets/index-C5Ighs_C.css +1 -0
- package/out/renderer/assets/index-Ckvy9Zge.js +1 -0
- package/out/renderer/assets/{index-Dn3kYWFt.js → index-D-TXozHA.js} +9 -9
- package/out/renderer/assets/index-DHKnfVbX.css +1 -0
- package/out/renderer/assets/index-DTc-sJ8S.js +7 -0
- package/out/renderer/assets/index-vK67PDia.js +784 -0
- package/out/renderer/assets/infoDiagram-PH2N3AL5-DYtVGJC7.js +2 -0
- package/out/renderer/assets/installer-BcSiJA6N.js +1 -0
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-B6AH0Dcn.js → journeyDiagram-U35MCT3I-vVg2sFTp.js} +6 -6
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-C7dciPrH.js → kanban-definition-NDS4AKOZ-BE36wSk2.js} +4 -4
- package/out/renderer/assets/{layout-hxpgEDIm.js → layout-bOQrw0b8.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-C6kd3fjG.js → legacy-agents-page-BSKz_UrV.js} +5 -5
- package/out/renderer/assets/{mermaid.core-CC8CflzC.js → mermaid.core-DpvY6Bhk.js} +5 -5
- package/out/renderer/assets/mesh-page-9Q8Sc9J_.js +1 -0
- package/out/renderer/assets/mindmap-definition-ALO5MXBD-B9PPN6sb.js +95 -0
- package/out/renderer/assets/mini-ySULdryU.js +1 -0
- package/out/renderer/assets/org-surface-gate-Dl4zcl5q.js +1 -0
- package/out/renderer/assets/{page-header-Dt6h8jvu.js → page-header-DazB-GQz.js} +1 -1
- package/out/renderer/assets/pieDiagram-IB7DONF6-DkioNhQY.js +30 -0
- package/out/renderer/assets/projects-page-C37RiUJz.js +35 -0
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-bRmQaOWY.js → quadrantDiagram-7GDLP6J5-4m3m0N6F.js} +4 -4
- package/out/renderer/assets/{radar-MK3ICKWK-B1I3333M.js → radar-MK3ICKWK-DS8YGAOb.js} +1 -1
- package/out/renderer/assets/radient-auth-buttons-DZeHRL7u.js +1 -0
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-B29w6CHz.js → requirementDiagram-KVF5MWMF-DsBdUu3C.js} +3 -3
- package/out/renderer/assets/sankeyDiagram-QLVOVGJD-CnaPYKR6.js +10 -0
- package/out/renderer/assets/{schedules-page-CXz63fN5.js → schedules-page-B0dSGpXt.js} +12 -12
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-D7gyUvnw.js → sequenceDiagram-X6HHIX6F-C3eja1QY.js} +2 -2
- package/out/renderer/assets/settings-page-CrMsVX3d.js +292 -0
- package/out/renderer/assets/{settings-section-DMXSpP_D.js → settings-section-BGG4XzV0.js} +1 -1
- package/out/renderer/assets/stateDiagram-DGXRK772-CjFKiyXn.js +1 -0
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BsbYpgkp.js +1 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-MePOCWzB.js → timeline-definition-BDJGKUSR-CAXy0nQD.js} +2 -2
- package/out/renderer/assets/ui-preferences-store-B6Fr0UX9.js +1 -0
- package/out/renderer/assets/{use-download-agent-mutation-BNAfnIa9.js → use-download-agent-mutation-LsNre_-6.js} +2 -2
- package/out/renderer/assets/use-memberships-query-BgiSfYgr.js +1 -0
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-heZP1JY-.js → xychartDiagram-VJFVF3MP-CfNm8SWG.js} +6 -6
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +9 -9
- package/out/renderer/installer.html +4 -5
- package/out/renderer/mini.html +7 -6
- package/package.json +3 -4
- package/out/renderer/assets/agents-page-CbQN_5wE.js +0 -7
- package/out/renderer/assets/aida-control-BuMafqCb.js +0 -50
- package/out/renderer/assets/arc-BG4bHuQI.js +0 -1
- package/out/renderer/assets/architectureDiagram-IEHRJDOE-CkYkkIY9.js +0 -36
- package/out/renderer/assets/browser-page-CIhGr6vl.js +0 -1
- package/out/renderer/assets/browser-webauthn-prompt-CYou_6QY.js +0 -1
- package/out/renderer/assets/channel-B-eIVFbM.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BN6aG5Qf.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BN6aG5Qf.js +0 -1
- package/out/renderer/assets/clone-C3CHGd7j.js +0 -1
- package/out/renderer/assets/dagre-OKDRZEBW-CBRdPb8k.js +0 -4
- package/out/renderer/assets/diagram-SSKATNLV-DyGZgIL1.js +0 -43
- package/out/renderer/assets/diagram-VNBRO52H-Con45RzE.js +0 -24
- package/out/renderer/assets/error-boundary-CdtTgj_c.js +0 -6
- package/out/renderer/assets/gitGraphDiagram-7IBYFJ6S-BO_dix1Z.js +0 -65
- package/out/renderer/assets/index-2qmFWi_F.css +0 -1
- package/out/renderer/assets/index-Bi4c5ZZH.js +0 -7
- package/out/renderer/assets/index-CIj3B-eB.js +0 -1
- package/out/renderer/assets/index-COUHPq03.js +0 -1533
- package/out/renderer/assets/index-D8ujEXbz.css +0 -1
- package/out/renderer/assets/infoDiagram-PH2N3AL5-BqRYyG2a.js +0 -2
- package/out/renderer/assets/installer-zpOWwoWQ.js +0 -1
- package/out/renderer/assets/mesh-page-M4Y20e0t.js +0 -2
- package/out/renderer/assets/mindmap-definition-ALO5MXBD-BWI1IBWM.js +0 -95
- package/out/renderer/assets/mini-Dtj-bCUA.js +0 -1
- package/out/renderer/assets/org-surface-gate-CjPxDSXP.js +0 -1
- package/out/renderer/assets/pieDiagram-IB7DONF6-DNymJR3P.js +0 -30
- package/out/renderer/assets/projects-page-C3N6NYIX.js +0 -35
- package/out/renderer/assets/radient-auth-buttons-CCXHTNWU.js +0 -1
- package/out/renderer/assets/sankeyDiagram-QLVOVGJD-BNv_qf23.js +0 -10
- package/out/renderer/assets/settings-page-CsCf63si.js +0 -292
- package/out/renderer/assets/stateDiagram-DGXRK772-Dd3BswSO.js +0 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-D9cOpOSm.js +0 -1
- package/out/renderer/assets/textarea-DsHM-W2p.js +0 -121
- package/out/renderer/assets/ui-preferences-store-BmAT9G_p.js +0 -1
- package/out/renderer/assets/use-memberships-query-PWqngUAl.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -62,11 +62,14 @@ function pairingHasRemedy(cause) {
|
|
|
62
62
|
const id$1 = zod.z.string().min(1).max(128).regex(/^[a-zA-Z0-9_-]+$/);
|
|
63
63
|
const settingKey = zod.z.string().min(1).max(256).regex(/^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$/);
|
|
64
64
|
const secret = zod.z.string().min(1).max(32768);
|
|
65
|
-
const
|
|
65
|
+
const sessionIdPattern = /^[a-f0-9]{12}$/;
|
|
66
|
+
const sessionId = zod.z.string().regex(sessionIdPattern);
|
|
67
|
+
const skillCwd = zod.z.string().min(1).max(4096);
|
|
66
68
|
const mcpServerName = zod.z.string().regex(/^[A-Za-z0-9_.:-]{1,100}$/);
|
|
67
69
|
const mcpSecretReference = zod.z.string().regex(/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/);
|
|
68
70
|
const mcpOperationId = zod.z.string().regex(/^[a-f0-9]{32}$/);
|
|
69
|
-
const
|
|
71
|
+
const mcpCatalogCwdPattern = /^(\/|[A-Za-z]:[\\/])/;
|
|
72
|
+
const mcpCatalogCwd = zod.z.string().min(1).max(4096).regex(mcpCatalogCwdPattern);
|
|
70
73
|
const SUBSCRIPTION_ID_PATTERN = /^[a-f0-9]{32}$/;
|
|
71
74
|
const requestId = zod.z.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
72
75
|
const meshId = zod.z.string().regex(/^[A-Za-z0-9_-]{1,128}$/);
|
|
@@ -262,6 +265,7 @@ const projectKey = zod.z.string().min(1).max(64);
|
|
|
262
265
|
const PROJECT_PROGRESS_MAX_CHARS = 1e3;
|
|
263
266
|
const PROJECT_DESCRIPTION_MAX_CHARS = 240;
|
|
264
267
|
const PROJECT_MILESTONE_NAME_MAX_CHARS = 80;
|
|
268
|
+
const hubItemKind = zod.z.enum(["agent", "team"]);
|
|
265
269
|
const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
266
270
|
zod.z.object({ op: zod.z.literal("capabilities") }).strict(),
|
|
267
271
|
zod.z.object({ op: zod.z.literal("profiles.list") }).strict(),
|
|
@@ -282,6 +286,47 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
282
286
|
requestId,
|
|
283
287
|
fields: profileFields
|
|
284
288
|
}).strict(),
|
|
289
|
+
/*
|
|
290
|
+
* THE HUB AUTO-UPDATE PLANE (backend `server/routes/desktop_hub.py`, gated by
|
|
291
|
+
* the `hub_updates` capability). `hub.updates` is a STORE READ on the backend
|
|
292
|
+
* (no network, O(items)), which is what makes it safe to poll from the
|
|
293
|
+
* sidebar; the five mutations are the ones that touch the hub or write a
|
|
294
|
+
* local definition, and each carries a `requestId` so a lost response is
|
|
295
|
+
* replayed by the server's receipts rather than re-run.
|
|
296
|
+
*
|
|
297
|
+
* `kind` is closed to the two definition families the hub carries, and `name`
|
|
298
|
+
* is the profile/team NAME because names are the runtime's attachment keys.
|
|
299
|
+
* `prefer` is per-item only: the backend refuses it on apply-all, since a
|
|
300
|
+
* conflict decision cannot be made for a set of items at once, so the
|
|
301
|
+
* apply-all schema does not offer it.
|
|
302
|
+
*/
|
|
303
|
+
zod.z.object({ op: zod.z.literal("hub.updates") }).strict(),
|
|
304
|
+
zod.z.object({
|
|
305
|
+
op: zod.z.literal("hub.check"),
|
|
306
|
+
requestId,
|
|
307
|
+
kind: hubItemKind.optional(),
|
|
308
|
+
name: profileName.optional()
|
|
309
|
+
}).strict(),
|
|
310
|
+
zod.z.object({
|
|
311
|
+
op: zod.z.literal("hub.apply"),
|
|
312
|
+
requestId,
|
|
313
|
+
kind: hubItemKind,
|
|
314
|
+
name: profileName,
|
|
315
|
+
prefer: zod.z.enum(["local", "remote"]).optional(),
|
|
316
|
+
acknowledgeUnknownBaseline: zod.z.boolean().optional(),
|
|
317
|
+
dryRun: zod.z.boolean().optional()
|
|
318
|
+
}).strict(),
|
|
319
|
+
zod.z.object({
|
|
320
|
+
op: zod.z.literal("hub.applyAll"),
|
|
321
|
+
requestId,
|
|
322
|
+
kind: hubItemKind.optional()
|
|
323
|
+
}).strict(),
|
|
324
|
+
zod.z.object({
|
|
325
|
+
op: zod.z.literal("hub.retry"),
|
|
326
|
+
requestId,
|
|
327
|
+
kind: hubItemKind,
|
|
328
|
+
name: profileName
|
|
329
|
+
}).strict(),
|
|
285
330
|
zod.z.object({ op: zod.z.literal("teams.list") }).strict(),
|
|
286
331
|
zod.z.object({ op: zod.z.literal("teams.get"), name: profileName }).strict(),
|
|
287
332
|
zod.z.object({
|
|
@@ -1163,7 +1208,20 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
1163
1208
|
*/
|
|
1164
1209
|
recentLimit: zod.z.number().int().min(0).max(50).optional()
|
|
1165
1210
|
}).strict(),
|
|
1166
|
-
zod.z.object({
|
|
1211
|
+
zod.z.object({
|
|
1212
|
+
op: zod.z.literal("skills.list"),
|
|
1213
|
+
/*
|
|
1214
|
+
* The sessionless arm's pair, both optional, `cwd` wins when both are sent
|
|
1215
|
+
* (the explicit folder beats the implied one; the route's docstring owns
|
|
1216
|
+
* the rule). `cwd` given → the folder's own discovery roots (identical to
|
|
1217
|
+
* the session created there); `session_id` given → the session's cwd
|
|
1218
|
+
* (compat, for the `/skills` panel and released clients); NEITHER → the
|
|
1219
|
+
* daemon's home roots, explicitly — never the daemon's process cwd.
|
|
1220
|
+
*/
|
|
1221
|
+
sessionId: sessionId.optional(),
|
|
1222
|
+
cwd: skillCwd.optional(),
|
|
1223
|
+
name: id$1.optional()
|
|
1224
|
+
}).strict(),
|
|
1167
1225
|
zod.z.object({ op: zod.z.literal("sessions.failovers"), sessionId }).strict(),
|
|
1168
1226
|
zod.z.object({
|
|
1169
1227
|
op: zod.z.literal("sessions.credential"),
|
|
@@ -1860,11 +1918,36 @@ function moveClientBoundMs(shape) {
|
|
|
1860
1918
|
const waitS = Math.max(0, shape.waitS ?? 0);
|
|
1861
1919
|
return (MOVE_OP_DEADLINE_S + hold + MOVE_CONTROL_SLACK_S + MOVE_CLIENT_MARGIN_S) * 1e3 + waitS * 1e3;
|
|
1862
1920
|
}
|
|
1921
|
+
const HUB_ITEM_MERGE_S = 120;
|
|
1922
|
+
const HUB_ITEM_WRITE_DEADLINE_MS = (HUB_ITEM_MERGE_S + 30 + MOVE_CLIENT_MARGIN_S) * 1e3;
|
|
1923
|
+
const HUB_CHECK_DEADLINE_MS = 6e4;
|
|
1924
|
+
const HUB_APPLY_ALL_DEADLINE_MS = 5 * HUB_ITEM_WRITE_DEADLINE_MS;
|
|
1925
|
+
const HUB_WRITE_OPS = /* @__PURE__ */ new Set([
|
|
1926
|
+
"hub.apply",
|
|
1927
|
+
"hub.retry",
|
|
1928
|
+
"hub.check",
|
|
1929
|
+
"hub.applyAll"
|
|
1930
|
+
]);
|
|
1931
|
+
function hubWriteDeadlineMs(op) {
|
|
1932
|
+
switch (op) {
|
|
1933
|
+
case "hub.apply":
|
|
1934
|
+
case "hub.retry":
|
|
1935
|
+
return HUB_ITEM_WRITE_DEADLINE_MS;
|
|
1936
|
+
case "hub.check":
|
|
1937
|
+
return HUB_CHECK_DEADLINE_MS;
|
|
1938
|
+
case "hub.applyAll":
|
|
1939
|
+
return HUB_APPLY_ALL_DEADLINE_MS;
|
|
1940
|
+
default:
|
|
1941
|
+
return null;
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1863
1944
|
function desktopRequestDeadlineMs(request) {
|
|
1864
1945
|
if (typeof request !== "string" && request.op === "sessions.transfer") {
|
|
1865
1946
|
return moveClientBoundMs(request) + MOVE_APP_MARGIN_MS;
|
|
1866
1947
|
}
|
|
1867
1948
|
const op = typeof request === "string" ? request : request.op;
|
|
1949
|
+
const hub = hubWriteDeadlineMs(op);
|
|
1950
|
+
if (hub !== null) return hub;
|
|
1868
1951
|
return LONG_READ_OPS.has(op) ? DESKTOP_LONG_READ_DEADLINE_MS : DESKTOP_CONTROL_DEADLINE_MS;
|
|
1869
1952
|
}
|
|
1870
1953
|
const DESKTOP_DEADLINE_EXCEEDED_CODE = "deadline_exceeded";
|
|
@@ -1878,6 +1961,7 @@ const READ_ONLY_OPS = /* @__PURE__ */ new Set([
|
|
|
1878
1961
|
"commands.list",
|
|
1879
1962
|
"config.get",
|
|
1880
1963
|
"credentials.list",
|
|
1964
|
+
"hub.updates",
|
|
1881
1965
|
"info.get",
|
|
1882
1966
|
"instructions.get",
|
|
1883
1967
|
"legacy.agent.get",
|
|
@@ -1934,6 +2018,12 @@ function desktopRequestDeadlineDetail(op, deadlineMs) {
|
|
|
1934
2018
|
message: `The app waits up to ${seconds} seconds for a move, and it was still running when the app stopped waiting. The move was asked for, so its outcome is unknown from here: read the session again before moving it anywhere else.`
|
|
1935
2019
|
};
|
|
1936
2020
|
}
|
|
2021
|
+
if (HUB_WRITE_OPS.has(op)) {
|
|
2022
|
+
return {
|
|
2023
|
+
code,
|
|
2024
|
+
message: "This is taking longer than expected. It may still finish; the mark will update."
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
1937
2027
|
if (READ_ONLY_OPS.has(op)) {
|
|
1938
2028
|
return {
|
|
1939
2029
|
code,
|
|
@@ -2062,6 +2152,52 @@ function desktopEndpoint(request) {
|
|
|
2062
2152
|
method: "PATCH",
|
|
2063
2153
|
body: { request_id: request.requestId, ...request.fields }
|
|
2064
2154
|
};
|
|
2155
|
+
case "hub.updates":
|
|
2156
|
+
return { path: "/v1/desktop/hub/updates", method: "GET" };
|
|
2157
|
+
case "hub.check":
|
|
2158
|
+
return {
|
|
2159
|
+
path: "/v1/desktop/hub/updates/check",
|
|
2160
|
+
method: "POST",
|
|
2161
|
+
body: {
|
|
2162
|
+
request_id: request.requestId,
|
|
2163
|
+
...request.kind ? { kind: request.kind } : {},
|
|
2164
|
+
...request.name ? { name: request.name } : {}
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
2167
|
+
case "hub.apply":
|
|
2168
|
+
return {
|
|
2169
|
+
path: "/v1/desktop/hub/updates/apply",
|
|
2170
|
+
method: "POST",
|
|
2171
|
+
body: {
|
|
2172
|
+
request_id: request.requestId,
|
|
2173
|
+
kind: request.kind,
|
|
2174
|
+
name: request.name,
|
|
2175
|
+
...request.prefer ? { prefer: request.prefer } : {},
|
|
2176
|
+
...request.acknowledgeUnknownBaseline !== void 0 ? {
|
|
2177
|
+
acknowledge_unknown_baseline: request.acknowledgeUnknownBaseline
|
|
2178
|
+
} : {},
|
|
2179
|
+
...request.dryRun !== void 0 ? { dry_run: request.dryRun } : {}
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
case "hub.applyAll":
|
|
2183
|
+
return {
|
|
2184
|
+
path: "/v1/desktop/hub/updates/apply-all",
|
|
2185
|
+
method: "POST",
|
|
2186
|
+
body: {
|
|
2187
|
+
request_id: request.requestId,
|
|
2188
|
+
...request.kind ? { kind: request.kind } : {}
|
|
2189
|
+
}
|
|
2190
|
+
};
|
|
2191
|
+
case "hub.retry":
|
|
2192
|
+
return {
|
|
2193
|
+
path: "/v1/desktop/hub/updates/retry",
|
|
2194
|
+
method: "POST",
|
|
2195
|
+
body: {
|
|
2196
|
+
request_id: request.requestId,
|
|
2197
|
+
kind: request.kind,
|
|
2198
|
+
name: request.name
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2065
2201
|
case "teams.list":
|
|
2066
2202
|
return { path: "/v1/desktop/teams", method: "GET" };
|
|
2067
2203
|
case "teams.get":
|
|
@@ -2684,11 +2820,17 @@ function desktopEndpoint(request) {
|
|
|
2684
2820
|
method: "GET"
|
|
2685
2821
|
};
|
|
2686
2822
|
}
|
|
2687
|
-
case "skills.list":
|
|
2823
|
+
case "skills.list": {
|
|
2824
|
+
const query = new URLSearchParams();
|
|
2825
|
+
if (request.sessionId) query.set("session_id", request.sessionId);
|
|
2826
|
+
if (request.cwd) query.set("cwd", request.cwd);
|
|
2827
|
+
if (request.name) query.set("name", request.name);
|
|
2828
|
+
const encoded = query.toString();
|
|
2688
2829
|
return {
|
|
2689
|
-
path: `/v1/desktop/skills
|
|
2830
|
+
path: `/v1/desktop/skills${encoded ? `?${encoded}` : ""}`,
|
|
2690
2831
|
method: "GET"
|
|
2691
2832
|
};
|
|
2833
|
+
}
|
|
2692
2834
|
case "sessions.failovers":
|
|
2693
2835
|
return {
|
|
2694
2836
|
path: `/v1/desktop/sessions/${request.sessionId}/failovers`,
|
|
@@ -2968,6 +3110,9 @@ const MINI_VIEW_SUMMONED = "mini-view:summoned";
|
|
|
2968
3110
|
const MINI_VIEW_DISMISS = "mini-view:dismiss";
|
|
2969
3111
|
const MINI_VIEW_REGISTRATION = "mini-view:registration";
|
|
2970
3112
|
const MINI_VIEW_REGISTRATION_GET = "mini-view:registration-get";
|
|
3113
|
+
const MINI_VIEW_RESIZE = "mini-view:resize";
|
|
3114
|
+
const MINI_VIEW_DIALOG = "mini-view:dialog";
|
|
3115
|
+
const MINI_VIEW_PAINTED = "mini-view:painted";
|
|
2971
3116
|
const MINI_VIEW_DISMISS_REASONS = [
|
|
2972
3117
|
"escape",
|
|
2973
3118
|
"blur",
|
|
@@ -2979,6 +3124,10 @@ function isMiniViewDismissReason(value) {
|
|
|
2979
3124
|
}
|
|
2980
3125
|
const MINI_VIEW_WIDTH = 640;
|
|
2981
3126
|
const MINI_VIEW_HEIGHT = 168;
|
|
3127
|
+
const MINI_VIEW_MAX_HEIGHT = 560;
|
|
3128
|
+
function isMiniViewResizePayload(value) {
|
|
3129
|
+
return value !== null && typeof value === "object" && typeof value.height === "number" && Number.isFinite(value.height);
|
|
3130
|
+
}
|
|
2982
3131
|
const DEFAULT_QUICK_SEND_VALUE = "primary+alt+shift+space";
|
|
2983
3132
|
const FUNCTION_KEY_TOKEN = /^f([1-9]|1[0-9]|2[0-4])$/;
|
|
2984
3133
|
function isFunctionKeyToken(token) {
|
|
@@ -33106,17 +33255,43 @@ const MINI_DOCUMENT = "mini.html";
|
|
|
33106
33255
|
function miniViewUrlFor(rendererUrl) {
|
|
33107
33256
|
return INDEX_DOCUMENT_SUFFIX.test(rendererUrl) ? rendererUrl.replace(INDEX_DOCUMENT_SUFFIX, `/${MINI_DOCUMENT}`) : `${rendererUrl.replace(TRAILING_SLASH, "")}/${MINI_DOCUMENT}`;
|
|
33108
33257
|
}
|
|
33258
|
+
const MINI_VIEW_GROUND = "#22201c";
|
|
33259
|
+
const MINI_VIEW_PAINT_TIMEOUT_MS = 1500;
|
|
33260
|
+
function miniViewPresentationFor(input) {
|
|
33261
|
+
if (input.show !== "focus") return "present";
|
|
33262
|
+
if (input.painted) return "present";
|
|
33263
|
+
if (input.timedOut) return "error-surface";
|
|
33264
|
+
return "wait";
|
|
33265
|
+
}
|
|
33266
|
+
function miniViewErrorSurfaceHtml() {
|
|
33267
|
+
return `<!doctype html>
|
|
33268
|
+
<html><head><meta charset="utf-8" /><title>Quick send</title>
|
|
33269
|
+
<style>
|
|
33270
|
+
:root { color-scheme: dark; }
|
|
33271
|
+
html, body { margin: 0; height: 100%; background: ${MINI_VIEW_GROUND}; }
|
|
33272
|
+
body { display: flex; align-items: center; padding: 0 16px;
|
|
33273
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
33274
|
+
color: #c2bcb0; }
|
|
33275
|
+
p { margin: 0; }
|
|
33276
|
+
strong { font-weight: 600; color: #ef8078; }
|
|
33277
|
+
</style></head>
|
|
33278
|
+
<body><p><strong>Quick send could not open.</strong> Try the hotkey again, or restart Local Operator if it keeps failing.</p></body></html>`;
|
|
33279
|
+
}
|
|
33109
33280
|
function createMiniView(options) {
|
|
33110
33281
|
const window = new electron.BrowserWindow({
|
|
33111
33282
|
width: MINI_VIEW_WIDTH,
|
|
33112
33283
|
height: MINI_VIEW_HEIGHT,
|
|
33113
33284
|
/*
|
|
33114
|
-
* Sized in content, not window, terms
|
|
33115
|
-
*
|
|
33116
|
-
*
|
|
33285
|
+
* Sized in content, not window, terms, and the content size is now the
|
|
33286
|
+
* BASE of a measured range rather than the whole story: the restyle's
|
|
33287
|
+
* chrome (previews, the readings strip, the picker sheet) asks for more
|
|
33288
|
+
* through `MINI_VIEW_RESIZE` below, and this call is what makes the
|
|
33289
|
+
* page's viewport the number every frame is captured at.
|
|
33117
33290
|
*/
|
|
33118
33291
|
useContentSize: true,
|
|
33119
33292
|
show: false,
|
|
33293
|
+
/* The dark ground under an as-yet-unpainted document; see MINI_VIEW_GROUND. */
|
|
33294
|
+
backgroundColor: MINI_VIEW_GROUND,
|
|
33120
33295
|
// A composer that floats over other apps carries no frame of its own:
|
|
33121
33296
|
// the app's own rows are the entire surface, and the one sanctioned
|
|
33122
33297
|
// elevation step is the card's ground.
|
|
@@ -33164,7 +33339,91 @@ function createMiniView(options) {
|
|
|
33164
33339
|
if (process.platform === "darwin") {
|
|
33165
33340
|
window.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
|
33166
33341
|
}
|
|
33342
|
+
let paintedForLoad = false;
|
|
33343
|
+
let paintTimer = null;
|
|
33344
|
+
let paintWaiters = [];
|
|
33345
|
+
const settlePaint = (ready) => {
|
|
33346
|
+
if (paintTimer !== null) {
|
|
33347
|
+
clearTimeout(paintTimer);
|
|
33348
|
+
paintTimer = null;
|
|
33349
|
+
}
|
|
33350
|
+
paintedForLoad = ready;
|
|
33351
|
+
const waiting = paintWaiters;
|
|
33352
|
+
paintWaiters = [];
|
|
33353
|
+
for (const resolve of waiting) resolve();
|
|
33354
|
+
};
|
|
33355
|
+
const showErrorSurface = () => {
|
|
33356
|
+
if (disposed || window.isDestroyed()) return;
|
|
33357
|
+
settlePaint(false);
|
|
33358
|
+
void window.loadURL(
|
|
33359
|
+
`data:text/html;charset=utf-8,${encodeURIComponent(miniViewErrorSurfaceHtml())}`
|
|
33360
|
+
);
|
|
33361
|
+
window.webContents.once("did-finish-load", () => {
|
|
33362
|
+
if (disposed || window.isDestroyed()) return;
|
|
33363
|
+
positionForCursorDisplay();
|
|
33364
|
+
presentMiniView(window, options.show, {
|
|
33365
|
+
trigger: "mini-view",
|
|
33366
|
+
report: options.report
|
|
33367
|
+
});
|
|
33368
|
+
if (options.show === "focus") {
|
|
33369
|
+
window.webContents.send(MINI_VIEW_SUMMONED, {
|
|
33370
|
+
at: Date.now()
|
|
33371
|
+
});
|
|
33372
|
+
}
|
|
33373
|
+
});
|
|
33374
|
+
};
|
|
33375
|
+
window.webContents.on("did-start-loading", () => {
|
|
33376
|
+
paintedForLoad = false;
|
|
33377
|
+
});
|
|
33378
|
+
window.webContents.on(
|
|
33379
|
+
"did-fail-load",
|
|
33380
|
+
(_event, errorCode, errorDescription, validatedURL, isMainFrame) => {
|
|
33381
|
+
if (!isMainFrame) return;
|
|
33382
|
+
options.report?.(
|
|
33383
|
+
`[mini-view] load failed (${errorCode} ${errorDescription}) for ${validatedURL}; showing the error card`
|
|
33384
|
+
);
|
|
33385
|
+
showErrorSurface();
|
|
33386
|
+
}
|
|
33387
|
+
);
|
|
33388
|
+
window.webContents.on("render-process-gone", (_event, details) => {
|
|
33389
|
+
options.report?.(
|
|
33390
|
+
`[mini-view] renderer gone (${details.reason}); showing the error card`
|
|
33391
|
+
);
|
|
33392
|
+
showErrorSurface();
|
|
33393
|
+
});
|
|
33167
33394
|
void window.loadURL(options.url);
|
|
33395
|
+
const onResize = (event, payload) => {
|
|
33396
|
+
if (window.isDestroyed() || event.sender !== window.webContents || event.senderFrame !== window.webContents.mainFrame) {
|
|
33397
|
+
return;
|
|
33398
|
+
}
|
|
33399
|
+
if (!isMiniViewResizePayload(payload)) return;
|
|
33400
|
+
const area = electron.screen.getDisplayMatching(window.getBounds()).workArea;
|
|
33401
|
+
const ceiling = Math.max(
|
|
33402
|
+
MINI_VIEW_HEIGHT,
|
|
33403
|
+
Math.min(MINI_VIEW_MAX_HEIGHT, area.height - 64)
|
|
33404
|
+
);
|
|
33405
|
+
const height = Math.max(
|
|
33406
|
+
MINI_VIEW_HEIGHT,
|
|
33407
|
+
Math.min(Math.round(payload.height), ceiling)
|
|
33408
|
+
);
|
|
33409
|
+
const bounds = window.getContentBounds();
|
|
33410
|
+
if (bounds.height === height) return;
|
|
33411
|
+
window.setContentSize(MINI_VIEW_WIDTH, height);
|
|
33412
|
+
const bottom = bounds.y + height;
|
|
33413
|
+
if (bottom > area.y + area.height) {
|
|
33414
|
+
window.setPosition(
|
|
33415
|
+
bounds.x,
|
|
33416
|
+
Math.max(area.y, area.y + area.height - height)
|
|
33417
|
+
);
|
|
33418
|
+
}
|
|
33419
|
+
};
|
|
33420
|
+
electron.ipcMain.on(MINI_VIEW_RESIZE, onResize);
|
|
33421
|
+
const onPainted = (event) => {
|
|
33422
|
+
if (window.isDestroyed() || event.sender !== window.webContents || event.senderFrame !== window.webContents.mainFrame)
|
|
33423
|
+
return;
|
|
33424
|
+
settlePaint(true);
|
|
33425
|
+
};
|
|
33426
|
+
electron.ipcMain.on(MINI_VIEW_PAINTED, onPainted);
|
|
33168
33427
|
let disposed = false;
|
|
33169
33428
|
function hide() {
|
|
33170
33429
|
if (disposed || window.isDestroyed()) return;
|
|
@@ -33194,42 +33453,86 @@ function createMiniView(options) {
|
|
|
33194
33453
|
}
|
|
33195
33454
|
hide();
|
|
33196
33455
|
});
|
|
33197
|
-
function
|
|
33198
|
-
if (disposed) return;
|
|
33199
|
-
|
|
33200
|
-
|
|
33456
|
+
function presentWhenReady() {
|
|
33457
|
+
if (disposed || window.isDestroyed()) return;
|
|
33458
|
+
const decision = miniViewPresentationFor({
|
|
33459
|
+
show: options.show,
|
|
33460
|
+
painted: paintedForLoad,
|
|
33461
|
+
timedOut: false
|
|
33462
|
+
});
|
|
33463
|
+
if (decision === "error-surface") {
|
|
33464
|
+
showErrorSurface();
|
|
33201
33465
|
return;
|
|
33202
33466
|
}
|
|
33467
|
+
if (decision === "present") {
|
|
33468
|
+
presentNow();
|
|
33469
|
+
return;
|
|
33470
|
+
}
|
|
33471
|
+
paintWaiters.push(() => {
|
|
33472
|
+
if (miniViewPresentationFor({
|
|
33473
|
+
show: options.show,
|
|
33474
|
+
painted: paintedForLoad,
|
|
33475
|
+
timedOut: false
|
|
33476
|
+
}) === "present")
|
|
33477
|
+
presentNow();
|
|
33478
|
+
});
|
|
33479
|
+
if (paintTimer === null) {
|
|
33480
|
+
paintTimer = setTimeout(() => {
|
|
33481
|
+
paintTimer = null;
|
|
33482
|
+
if (miniViewPresentationFor({
|
|
33483
|
+
show: options.show,
|
|
33484
|
+
painted: paintedForLoad,
|
|
33485
|
+
timedOut: true
|
|
33486
|
+
}) === "error-surface")
|
|
33487
|
+
showErrorSurface();
|
|
33488
|
+
}, MINI_VIEW_PAINT_TIMEOUT_MS);
|
|
33489
|
+
}
|
|
33490
|
+
}
|
|
33491
|
+
function presentNow() {
|
|
33492
|
+
if (disposed || window.isDestroyed()) return;
|
|
33203
33493
|
positionForCursorDisplay();
|
|
33204
33494
|
presentMiniView(window, options.show, {
|
|
33205
33495
|
trigger: "mini-view",
|
|
33206
33496
|
report: options.report
|
|
33207
33497
|
});
|
|
33208
|
-
if (options.show === "focus"
|
|
33209
|
-
|
|
33210
|
-
|
|
33498
|
+
if (options.show === "focus") {
|
|
33499
|
+
window.webContents.send(MINI_VIEW_SUMMONED, {
|
|
33500
|
+
at: Date.now()
|
|
33501
|
+
});
|
|
33211
33502
|
}
|
|
33212
33503
|
}
|
|
33504
|
+
function toggle() {
|
|
33505
|
+
if (disposed) return;
|
|
33506
|
+
if (!window.isDestroyed() && window.isVisible()) {
|
|
33507
|
+
hide();
|
|
33508
|
+
return;
|
|
33509
|
+
}
|
|
33510
|
+
presentWhenReady();
|
|
33511
|
+
}
|
|
33213
33512
|
function positionForCursorDisplay() {
|
|
33214
33513
|
if (window.isDestroyed()) return;
|
|
33215
33514
|
const display = electron.screen.getDisplayNearestPoint(
|
|
33216
33515
|
electron.screen.getCursorScreenPoint()
|
|
33217
33516
|
);
|
|
33218
33517
|
const area = display.workArea;
|
|
33518
|
+
const height = window.isDestroyed() ? MINI_VIEW_HEIGHT : window.getContentBounds().height;
|
|
33219
33519
|
const x = Math.round(area.x + (area.width - MINI_VIEW_WIDTH) / 2);
|
|
33220
|
-
const desiredY = area.y + area.height / 3 -
|
|
33520
|
+
const desiredY = area.y + area.height / 3 - height / 2;
|
|
33221
33521
|
const y = Math.round(
|
|
33222
|
-
Math.min(
|
|
33223
|
-
Math.max(desiredY, area.y),
|
|
33224
|
-
area.y + area.height - MINI_VIEW_HEIGHT
|
|
33225
|
-
)
|
|
33522
|
+
Math.min(Math.max(desiredY, area.y), area.y + area.height - height)
|
|
33226
33523
|
);
|
|
33227
33524
|
window.setPosition(x, y);
|
|
33228
33525
|
}
|
|
33229
33526
|
function dispose() {
|
|
33230
33527
|
if (disposed) return;
|
|
33231
33528
|
disposed = true;
|
|
33529
|
+
electron.ipcMain.removeListener(MINI_VIEW_RESIZE, onResize);
|
|
33530
|
+
electron.ipcMain.removeListener(MINI_VIEW_PAINTED, onPainted);
|
|
33232
33531
|
electron.ipcMain.removeHandler(MINI_VIEW_DISMISS);
|
|
33532
|
+
if (paintTimer !== null) {
|
|
33533
|
+
clearTimeout(paintTimer);
|
|
33534
|
+
paintTimer = null;
|
|
33535
|
+
}
|
|
33233
33536
|
if (!window.isDestroyed()) window.destroy();
|
|
33234
33537
|
}
|
|
33235
33538
|
return { window, toggle, hide, dispose };
|
|
@@ -40376,9 +40679,15 @@ if (process.platform === "darwin" && electron.app.dock) {
|
|
|
40376
40679
|
if (windowLaunch.hideDock) {
|
|
40377
40680
|
electron.app.dock.hide();
|
|
40378
40681
|
} else {
|
|
40682
|
+
electron.app.dock.show();
|
|
40379
40683
|
electron.app.dock.setIcon(image);
|
|
40380
40684
|
}
|
|
40381
40685
|
}
|
|
40686
|
+
function reassertDockParticipation() {
|
|
40687
|
+
if (process.platform !== "darwin" || !electron.app.dock) return;
|
|
40688
|
+
if (windowLaunch.hideDock) return;
|
|
40689
|
+
electron.app.dock.show();
|
|
40690
|
+
}
|
|
40382
40691
|
const telemetryLaunch = resolveTelemetryLaunch({
|
|
40383
40692
|
env: launchEnv,
|
|
40384
40693
|
projectKey: backendConfig.VITE_PUBLIC_POSTHOG_KEY
|
|
@@ -41566,24 +41875,37 @@ electron.app.whenReady().then(async () => {
|
|
|
41566
41875
|
return false;
|
|
41567
41876
|
}
|
|
41568
41877
|
});
|
|
41569
|
-
electron.ipcMain.handle("show-open-dialog", async (
|
|
41570
|
-
|
|
41878
|
+
electron.ipcMain.handle("show-open-dialog", async (event, options) => {
|
|
41879
|
+
const parent = electron.BrowserWindow.fromWebContents(event.sender) ?? mainWindow;
|
|
41880
|
+
if (!parent) {
|
|
41571
41881
|
logger.error(
|
|
41572
|
-
"Cannot show open dialog:
|
|
41882
|
+
"Cannot show open dialog: no window can own it.",
|
|
41573
41883
|
LogFileType.BACKEND
|
|
41574
41884
|
);
|
|
41575
41885
|
return { canceled: true, filePaths: [] };
|
|
41576
41886
|
}
|
|
41577
|
-
const
|
|
41578
|
-
|
|
41579
|
-
|
|
41580
|
-
|
|
41581
|
-
|
|
41582
|
-
|
|
41583
|
-
|
|
41584
|
-
|
|
41585
|
-
|
|
41586
|
-
|
|
41887
|
+
const mini = miniView;
|
|
41888
|
+
const fromMini = mini !== null && !mini.window.isDestroyed() && event.sender === mini.window.webContents;
|
|
41889
|
+
const dialogPayload = { open: true };
|
|
41890
|
+
if (fromMini)
|
|
41891
|
+
mini.window.webContents.send(MINI_VIEW_DIALOG, dialogPayload);
|
|
41892
|
+
try {
|
|
41893
|
+
const result = await electron.dialog.showOpenDialog(
|
|
41894
|
+
parent,
|
|
41895
|
+
withRememberedDirectory(
|
|
41896
|
+
"open-file",
|
|
41897
|
+
options,
|
|
41898
|
+
pickerFallbackDirectory()
|
|
41899
|
+
)
|
|
41900
|
+
);
|
|
41901
|
+
rememberPickedDirectory("open-file", result.filePaths);
|
|
41902
|
+
return result;
|
|
41903
|
+
} finally {
|
|
41904
|
+
if (fromMini && mini !== null && !mini.window.isDestroyed())
|
|
41905
|
+
mini.window.webContents.send(MINI_VIEW_DIALOG, {
|
|
41906
|
+
open: false
|
|
41907
|
+
});
|
|
41908
|
+
}
|
|
41587
41909
|
});
|
|
41588
41910
|
electron.ipcMain.handle("select-directory", async () => {
|
|
41589
41911
|
if (!mainWindow) {
|
|
@@ -41992,6 +42314,7 @@ electron.app.whenReady().then(async () => {
|
|
|
41992
42314
|
};
|
|
41993
42315
|
setupMainWindowWithUpdateService(launchSession, launchCatalogue);
|
|
41994
42316
|
electron.app.on("activate", () => {
|
|
42317
|
+
reassertDockParticipation();
|
|
41995
42318
|
if (electron.BrowserWindow.getAllWindows().length === 0) {
|
|
41996
42319
|
if (quitState.isQuitting()) {
|
|
41997
42320
|
reportSkippedWhileQuitting(
|
|
@@ -42031,6 +42354,13 @@ electron.app.on("window-all-closed", () => {
|
|
|
42031
42354
|
electron.app.quit();
|
|
42032
42355
|
return;
|
|
42033
42356
|
}
|
|
42357
|
+
if (quitState.isQuitting()) {
|
|
42358
|
+
logger.info(
|
|
42359
|
+
"All windows closed as part of a quit in progress; will-quit owns the completion",
|
|
42360
|
+
LogFileType.BACKEND
|
|
42361
|
+
);
|
|
42362
|
+
return;
|
|
42363
|
+
}
|
|
42034
42364
|
logger.info(
|
|
42035
42365
|
"All windows closed, but keeping app active (macOS platform)",
|
|
42036
42366
|
LogFileType.BACKEND
|
|
@@ -42070,7 +42400,7 @@ electron.app.on("will-quit", (event) => {
|
|
|
42070
42400
|
failsafe.unref();
|
|
42071
42401
|
void backendService.stop(false).then(() => {
|
|
42072
42402
|
clearTimeout(failsafe);
|
|
42073
|
-
electron.app.
|
|
42403
|
+
electron.app.exit(0);
|
|
42074
42404
|
}).catch((error) => {
|
|
42075
42405
|
clearTimeout(failsafe);
|
|
42076
42406
|
logger.error(
|
|
@@ -42089,22 +42419,33 @@ const holdQuitForSessionCookieSnapshot = createSessionCookieQuitHold({
|
|
|
42089
42419
|
});
|
|
42090
42420
|
electron.app.on("before-quit", async (event) => {
|
|
42091
42421
|
quitState.begin();
|
|
42422
|
+
electron.globalShortcut.unregisterAll();
|
|
42423
|
+
miniViewRegistrar?.dispose();
|
|
42424
|
+
quickSendWatcher?.stop();
|
|
42425
|
+
miniView?.dispose();
|
|
42426
|
+
if (windowLaunch.mode === "headless") {
|
|
42427
|
+
launcherWatch?.stop();
|
|
42428
|
+
armHeadlessExitDeadline("the app is quitting");
|
|
42429
|
+
}
|
|
42092
42430
|
if (await holdQuitForSessionCookieSnapshot(event)) return;
|
|
42093
42431
|
logger.info("App is about to quit", LogFileType.BACKEND);
|
|
42432
|
+
if (!backendService.isOwnedCleanupComplete()) {
|
|
42433
|
+
try {
|
|
42434
|
+
await backendService.stop(false);
|
|
42435
|
+
} catch (error) {
|
|
42436
|
+
logger.error(
|
|
42437
|
+
"Owned backend stop rejected during quit; continuing the shutdown",
|
|
42438
|
+
LogFileType.BACKEND,
|
|
42439
|
+
error
|
|
42440
|
+
);
|
|
42441
|
+
}
|
|
42442
|
+
}
|
|
42094
42443
|
if (parkedLaunches.length > 0) {
|
|
42095
42444
|
reportParksAtQuit(
|
|
42096
42445
|
parkedLaunches.map((parked) => parked.session),
|
|
42097
42446
|
reportRaise
|
|
42098
42447
|
);
|
|
42099
42448
|
}
|
|
42100
|
-
if (windowLaunch.mode === "headless") {
|
|
42101
|
-
launcherWatch?.stop();
|
|
42102
|
-
armHeadlessExitDeadline("the app is quitting");
|
|
42103
|
-
}
|
|
42104
|
-
electron.globalShortcut.unregisterAll();
|
|
42105
|
-
miniViewRegistrar?.dispose();
|
|
42106
|
-
quickSendWatcher?.stop();
|
|
42107
|
-
miniView?.dispose();
|
|
42108
42449
|
activeUpdateService?.quitForInFlightInstall("app quit");
|
|
42109
42450
|
void stopBrowserHost();
|
|
42110
42451
|
});
|
package/out/preload/index.js
CHANGED
|
@@ -94,6 +94,9 @@ const MINI_VIEW_SUMMONED = "mini-view:summoned";
|
|
|
94
94
|
const MINI_VIEW_DISMISS = "mini-view:dismiss";
|
|
95
95
|
const MINI_VIEW_REGISTRATION = "mini-view:registration";
|
|
96
96
|
const MINI_VIEW_REGISTRATION_GET = "mini-view:registration-get";
|
|
97
|
+
const MINI_VIEW_RESIZE = "mini-view:resize";
|
|
98
|
+
const MINI_VIEW_DIALOG = "mini-view:dialog";
|
|
99
|
+
const MINI_VIEW_PAINTED = "mini-view:painted";
|
|
97
100
|
const MINI_VIEW_REGISTRATION_STATUSES = [
|
|
98
101
|
"registered",
|
|
99
102
|
"taken",
|
|
@@ -114,6 +117,9 @@ function isMiniViewRegistrationState(value) {
|
|
|
114
117
|
state.status
|
|
115
118
|
);
|
|
116
119
|
}
|
|
120
|
+
function isMiniViewDialogPayload(value) {
|
|
121
|
+
return value !== null && typeof value === "object" && typeof value.open === "boolean";
|
|
122
|
+
}
|
|
117
123
|
const OPEN_SESSION_FLAG = "--open-session";
|
|
118
124
|
const OPEN_CATALOGUE_FLAG = "--open-catalogue";
|
|
119
125
|
const SESSION_ID = /^[a-f0-9]{12}$/;
|
|
@@ -1019,6 +1025,37 @@ const api = {
|
|
|
1019
1025
|
},
|
|
1020
1026
|
/** This window -> main: put the mini window away, naming the act. */
|
|
1021
1027
|
dismiss: (reason) => electron.ipcRenderer.invoke(MINI_VIEW_DISMISS, reason),
|
|
1028
|
+
/**
|
|
1029
|
+
* This window -> main: the content height this frame needs (design R2's
|
|
1030
|
+
* measure -> IPC -> resize). Fire-and-forget by design: the frame measures
|
|
1031
|
+
* on every layout settle, there is no answer to await, and main owns the
|
|
1032
|
+
* clamp - see `MINI_VIEW_RESIZE` in `src/shared/mini-view.ts`.
|
|
1033
|
+
*/
|
|
1034
|
+
resize: (height) => {
|
|
1035
|
+
electron.ipcRenderer.send(MINI_VIEW_RESIZE, { height });
|
|
1036
|
+
},
|
|
1037
|
+
/**
|
|
1038
|
+
* This window -> main: the document has committed its first paint, so the
|
|
1039
|
+
* window may be shown without flashing white (see `MINI_VIEW_PAINTED`).
|
|
1040
|
+
* Fire-and-forget, and sent once per load.
|
|
1041
|
+
*/
|
|
1042
|
+
painted: () => {
|
|
1043
|
+
electron.ipcRenderer.send(MINI_VIEW_PAINTED);
|
|
1044
|
+
},
|
|
1045
|
+
/**
|
|
1046
|
+
* Main -> this window: a native dialog the window opened is up, or answered.
|
|
1047
|
+
* The frame latches its blur-hide guard for the duration (see
|
|
1048
|
+
* `MINI_VIEW_DIALOG`).
|
|
1049
|
+
*/
|
|
1050
|
+
onDialog: (callback) => {
|
|
1051
|
+
const handler = (_event, payload) => {
|
|
1052
|
+
if (isMiniViewDialogPayload(payload)) callback(payload);
|
|
1053
|
+
};
|
|
1054
|
+
electron.ipcRenderer.on(MINI_VIEW_DIALOG, handler);
|
|
1055
|
+
return () => {
|
|
1056
|
+
electron.ipcRenderer.removeListener(MINI_VIEW_DIALOG, handler);
|
|
1057
|
+
};
|
|
1058
|
+
},
|
|
1022
1059
|
/** Main -> every renderer: the live global-shortcut state. */
|
|
1023
1060
|
onRegistration: (callback) => {
|
|
1024
1061
|
const handler = (_event, state) => {
|