local-operator-ui 0.31.18 → 0.31.20
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/README.md +24 -0
- package/out/main/index.js +233 -106
- package/out/renderer/assets/{_basePickBy-D1XXNWdy.js → _basePickBy-_G13yD_N.js} +1 -1
- package/out/renderer/assets/{_baseUniq-DD_DKvaU.js → _baseUniq-cZFY6WR-.js} +1 -1
- package/out/renderer/assets/{agent-details-page-Q8dgdQp2.js → agent-details-page-DohUpAW5.js} +1 -1
- package/out/renderer/assets/{agent-hub-page-CBHsotVj.js → agent-hub-page-D2Wo_RcW.js} +2 -2
- package/out/renderer/assets/agents-page-Bme3mW2i.js +2 -0
- package/out/renderer/assets/{renderer-platform-RsXXlY5x.js → aida-control-DVTI-DZP.js} +19 -19
- package/out/renderer/assets/{arc-BII0LAll.js → arc-_ZSLPSD3.js} +1 -1
- package/out/renderer/assets/architectureDiagram-IEHRJDOE-BMozIO-d.js +36 -0
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-BsfIO03o.js → blockDiagram-JOT3LUYC-CnCGGby6.js} +6 -6
- package/out/renderer/assets/{book-open-Bau36KjM.js → book-open-BWKY7M9P.js} +1 -1
- package/out/renderer/assets/browser-page-Ca86jJVo.js +1 -0
- package/out/renderer/assets/browser-webauthn-prompt-Zq7Sensn.js +1 -0
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-CHKu8u4B.js → c4Diagram-VJAJSXHY-D6vlxi2G.js} +1 -1
- package/out/renderer/assets/channel-DBxTgGZs.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-Do_SeY3I.js → chunk-4BMEZGHF-CgxwmKpR.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-C7_NoYUm.js → chunk-A2AXSNBT-DL4YbfpC.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-C3I1E4qy.js → chunk-AEK57VVT-C7STzYq2.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-BEkTCb-4.js → chunk-D6G4REZN-BiGlWxbN.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-Ccs-Kaym.js → chunk-RZ5BOZE2-FPI-zkVi.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-Db28vmME.js → chunk-XZIHB7SX-pQtxBw7K.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-oRXPz12L.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-oRXPz12L.js +1 -0
- package/out/renderer/assets/clone-CWgQ1AK5.js +1 -0
- package/out/renderer/assets/{console-mirror-CUQyeXIE.js → console-mirror-CG9RcMIb.js} +1 -1
- package/out/renderer/assets/{consoleCapture-emgU7WyW.js → consoleCapture-CpTo2RAv.js} +1 -1
- package/out/renderer/assets/dagre-OKDRZEBW-BoM7akd9.js +4 -0
- package/out/renderer/assets/diagram-SSKATNLV-D9w1aNay.js +43 -0
- package/out/renderer/assets/diagram-VNBRO52H-D6xO4h26.js +24 -0
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-BYRglvp5.js → erDiagram-Q7BY3M3F-lgEC_hRU.js} +1 -1
- package/out/renderer/assets/{error-boundary-BFYdHP26.js → error-boundary-DVk48CIF.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-C6ReCJC9.js → flowDiagram-4HSFHLVR-B8gXHejR.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-CMDShfzg.js → ganttDiagram-APWFNJXF-Ds8ML93J.js} +3 -3
- package/out/renderer/assets/gitGraphDiagram-7IBYFJ6S-D5gdmSVh.js +65 -0
- package/out/renderer/assets/{graph-BK-Vf19N.js → graph-DNi4FjaS.js} +1 -1
- package/out/renderer/assets/index-40tBsZ9r.js +7 -0
- package/out/renderer/assets/{index-BDPyvriR.js → index-BhRzR-VW.js} +391 -376
- package/out/renderer/assets/index-BlalL3ro.js +1 -0
- package/out/renderer/assets/index-FjyWTJXV.css +1 -0
- package/out/renderer/assets/infoDiagram-PH2N3AL5-BDTgzxhS.js +2 -0
- package/out/renderer/assets/{installer-DfFRjYBs.js → installer-BgW1Tkr8.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-CeBVrNEA.js → journeyDiagram-U35MCT3I-BdnGNrZc.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-DnIH3R0V.js → kanban-definition-NDS4AKOZ-BuQLa1-R.js} +1 -1
- package/out/renderer/assets/{layout-IqcTjCQI.js → layout-Pvac8TnM.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-DbLTVwq0.js → legacy-agents-page-BR_oPhtA.js} +3 -3
- package/out/renderer/assets/{mermaid.core-BrRc254F.js → mermaid.core-Dol6F2oY.js} +5 -5
- package/out/renderer/assets/mesh-page-CcSpUIcL.js +2 -0
- package/out/renderer/assets/mindmap-definition-ALO5MXBD-DDnWPtbR.js +95 -0
- package/out/renderer/assets/mini-D1QQjR0V.js +1 -0
- package/out/renderer/assets/org-surface-gate-_kP5Dpsg.js +1 -0
- package/out/renderer/assets/{page-header-BtO13sx8.js → page-header-B3RA2AMB.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-CnRMxjLj.js → pieDiagram-IB7DONF6-Dc1zeStB.js} +1 -1
- package/out/renderer/assets/{projects-page-BgRRDkEz.js → projects-page-Cb7bJ1ue.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-bRLUBm5r.js → quadrantDiagram-7GDLP6J5-AlzvyKPw.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-BV3WfB2Y.js → radar-MK3ICKWK-BLuijs-X.js} +1 -1
- package/out/renderer/assets/radient-auth-buttons-gtgUk3ts.js +1 -0
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-Bzqys165.js → requirementDiagram-KVF5MWMF-CfgMH9Xy.js} +1 -1
- package/out/renderer/assets/sankeyDiagram-QLVOVGJD-CGSaFjvZ.js +10 -0
- package/out/renderer/assets/{schedules-page-CbOATI1U.js → schedules-page-yCFUUqqb.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-bfcEv3LN.js → sequenceDiagram-X6HHIX6F-BKLpPHnF.js} +1 -1
- package/out/renderer/assets/settings-page-6S9zTaN7.js +297 -0
- package/out/renderer/assets/{settings-section-BXGO9Lv0.js → settings-section-D3WEX0WK.js} +1 -1
- package/out/renderer/assets/stateDiagram-DGXRK772-CukEj5Ge.js +1 -0
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-CaoB6DdD.js +1 -0
- package/out/renderer/assets/{textarea-B83uQCj2.js → textarea-BX6EeK34.js} +1 -1
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-BlN_DgVS.js → timeline-definition-BDJGKUSR-ZSpHRGCR.js} +1 -1
- package/out/renderer/assets/{ui-preferences-store-DzXZGWGz.js → ui-preferences-store-DjUQd2R7.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-DrENBWNa.js → use-download-agent-mutation-BwZi8Zfx.js} +2 -2
- package/out/renderer/assets/use-memberships-query-CSOmeH29.js +1 -0
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-C1DOS4ES.js → xychartDiagram-VJFVF3MP-B4P41D_W.js} +1 -1
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +8 -8
- package/out/renderer/installer.html +5 -5
- package/out/renderer/mini.html +6 -6
- package/package.json +2 -2
- package/out/renderer/assets/agents-page-9zkhLfa8.js +0 -2
- package/out/renderer/assets/architectureDiagram-IEHRJDOE-Yh4i0oDy.js +0 -36
- package/out/renderer/assets/browser-page-CrHmmBk0.js +0 -1
- package/out/renderer/assets/browser-webauthn-prompt-_nNd3iSK.js +0 -1
- package/out/renderer/assets/channel-DXiH5yDB.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-D2MG4USX.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-D2MG4USX.js +0 -1
- package/out/renderer/assets/clone-BDi6ICAs.js +0 -1
- package/out/renderer/assets/dagre-OKDRZEBW-k4D1AM8X.js +0 -4
- package/out/renderer/assets/diagram-SSKATNLV-B0DOtyf9.js +0 -43
- package/out/renderer/assets/diagram-VNBRO52H-BmzuI3Lr.js +0 -24
- package/out/renderer/assets/gitGraphDiagram-7IBYFJ6S-pvPc8CHP.js +0 -65
- package/out/renderer/assets/index-B5DwqFlK.js +0 -7
- package/out/renderer/assets/index-DITdBETY.css +0 -1
- package/out/renderer/assets/index-_oyU7kmX.js +0 -1
- package/out/renderer/assets/infoDiagram-PH2N3AL5-COePE42k.js +0 -2
- package/out/renderer/assets/mesh-page-W9oV_bPF.js +0 -2
- package/out/renderer/assets/mindmap-definition-ALO5MXBD-BMHndK7E.js +0 -95
- package/out/renderer/assets/mini-CbmMlUkq.js +0 -1
- package/out/renderer/assets/org-surface-gate-BgtTWHt3.js +0 -1
- package/out/renderer/assets/radient-auth-buttons-Briy2cZb.js +0 -1
- package/out/renderer/assets/sankeyDiagram-QLVOVGJD--IgSaXgN.js +0 -10
- package/out/renderer/assets/settings-page-Bn87mGZ1.js +0 -307
- package/out/renderer/assets/stateDiagram-DGXRK772-CDJAoYUf.js +0 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-Di7PMVrt.js +0 -1
- package/out/renderer/assets/use-memberships-query-C2Yus1QJ.js +0 -1
- /package/out/renderer/assets/{index-CDaH3A1m.js → index-VKe88JN9.js} +0 -0
package/out/main/index.js
CHANGED
|
@@ -78,6 +78,9 @@ const DESKTOP_MESSAGE_MAX_CHARS = 2e5;
|
|
|
78
78
|
const SESSION_SEARCH_MAX_CHARS = 256;
|
|
79
79
|
const SESSION_SEARCH_DEFAULT_LIMIT = 100;
|
|
80
80
|
const CHECKPOINT_WARM_MAX_IDS = 16;
|
|
81
|
+
const THREAD_FIND_MAX_CHARS = 256;
|
|
82
|
+
const THREAD_FIND_DEFAULT_LIMIT = 100;
|
|
83
|
+
const THREAD_FIND_MAX_LIMIT = 200;
|
|
81
84
|
const DESKTOP_SYSTEM_PROMPT_MAX_CHARS = 1e6;
|
|
82
85
|
const profileName = zod.z.string().min(1).max(128).refine(
|
|
83
86
|
(name) => name !== "." && name !== ".." && !name.includes("/") && !name.includes("\\") && [...name].every(
|
|
@@ -561,6 +564,30 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
561
564
|
ids: zod.z.array(id$1).max(CHECKPOINT_WARM_MAX_IDS).optional(),
|
|
562
565
|
limit: zod.z.number().int().min(1).max(CHECKPOINT_WARM_MAX_IDS).optional()
|
|
563
566
|
}).strict(),
|
|
567
|
+
/*
|
|
568
|
+
* In-thread find (D9): messages of ONE conversation matching `q`, best
|
|
569
|
+
* first, served from the per-session transcript index.
|
|
570
|
+
*
|
|
571
|
+
* A READ like `history` and `checkpoints` beside it. The answer's `state` is
|
|
572
|
+
* the checkpoint manifest's own ladder: a cold or stale index answers
|
|
573
|
+
* `building` inside the first-paint budget (with hits ranked from the
|
|
574
|
+
* previous scan marked `partial`) while the background refresh runs, so the
|
|
575
|
+
* overlay's first paint is immediate; `unsupported` is a peer conversation
|
|
576
|
+
* whose journal is not on this device; `error` is a failed refresh inside
|
|
577
|
+
* its cooldown. The overlay renders both tiers (`exact`/`soft`) and treats
|
|
578
|
+
* `ranges` as snippet-relative — empty on a soft hit, which has no literal
|
|
579
|
+
* occurrence of the query by construction.
|
|
580
|
+
*/
|
|
581
|
+
zod.z.object({
|
|
582
|
+
op: zod.z.literal("sessions.find"),
|
|
583
|
+
sessionId,
|
|
584
|
+
// `.min(1)`: an empty query is not a search. The overlay's client never
|
|
585
|
+
// sends one — it answers an empty query locally, without a request — so
|
|
586
|
+
// refusing it by name keeps the vocabulary closed rather than paying a
|
|
587
|
+
// round trip for an answer the box already knows.
|
|
588
|
+
q: zod.z.string().min(1).max(THREAD_FIND_MAX_CHARS),
|
|
589
|
+
limit: zod.z.number().int().min(1).max(THREAD_FIND_MAX_LIMIT).optional()
|
|
590
|
+
}).strict(),
|
|
564
591
|
/*
|
|
565
592
|
* One child's durable transcript, for the run panel's reader
|
|
566
593
|
* (`docs/run-sidebar.md` § 10.1, § 10.3).
|
|
@@ -1794,6 +1821,7 @@ const READ_ONLY_OPS = /* @__PURE__ */ new Set([
|
|
|
1794
1821
|
"sessions.aside.get",
|
|
1795
1822
|
"sessions.checkpoints",
|
|
1796
1823
|
"sessions.failovers",
|
|
1824
|
+
"sessions.find",
|
|
1797
1825
|
"sessions.get",
|
|
1798
1826
|
"sessions.history",
|
|
1799
1827
|
"sessions.list",
|
|
@@ -2086,6 +2114,16 @@ function desktopEndpoint(request) {
|
|
|
2086
2114
|
...request.limit !== void 0 ? { limit: request.limit } : {}
|
|
2087
2115
|
}
|
|
2088
2116
|
};
|
|
2117
|
+
case "sessions.find": {
|
|
2118
|
+
const query = new URLSearchParams({
|
|
2119
|
+
q: request.q,
|
|
2120
|
+
limit: String(request.limit ?? THREAD_FIND_DEFAULT_LIMIT)
|
|
2121
|
+
});
|
|
2122
|
+
return {
|
|
2123
|
+
path: `/v1/desktop/sessions/${request.sessionId}/find?${query}`,
|
|
2124
|
+
method: "GET"
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2089
2127
|
case "subagents.transcript": {
|
|
2090
2128
|
const query = new URLSearchParams({
|
|
2091
2129
|
limit: String(request.limit ?? 100)
|
|
@@ -2827,7 +2865,7 @@ function isMiniViewDismissReason(value) {
|
|
|
2827
2865
|
}
|
|
2828
2866
|
const MINI_VIEW_WIDTH = 640;
|
|
2829
2867
|
const MINI_VIEW_HEIGHT = 168;
|
|
2830
|
-
const DEFAULT_QUICK_SEND_VALUE = "primary+alt+space";
|
|
2868
|
+
const DEFAULT_QUICK_SEND_VALUE = "primary+alt+shift+space";
|
|
2831
2869
|
const FUNCTION_KEY_TOKEN = /^f([1-9]|1[0-9]|2[0-4])$/;
|
|
2832
2870
|
function isFunctionKeyToken(token) {
|
|
2833
2871
|
return FUNCTION_KEY_TOKEN.test(token);
|
|
@@ -11742,6 +11780,11 @@ const REFUSABLE_DELIVERY = {
|
|
|
11742
11780
|
// THE ONE REFUSAL. The residual above says what it rests on and what it cannot
|
|
11743
11781
|
// see.
|
|
11744
11782
|
"second-instance": "when-its-plan-is-silent",
|
|
11783
|
+
// A Dock click carries no conversation and installs nothing: it only ever
|
|
11784
|
+
// opens this process's own window, so there is no delivery here to refuse or
|
|
11785
|
+
// to park. (The refusal a QUITTING process answers it with is not this gate's;
|
|
11786
|
+
// it has a line of its own, `applied=skipped+quitting`.)
|
|
11787
|
+
activate: "never",
|
|
11745
11788
|
// A person clicked a real banner, so refusing it and applying it must not
|
|
11746
11789
|
// differ — and with a window up it does not even reach this gate.
|
|
11747
11790
|
"banner-click": "never",
|
|
@@ -11810,6 +11853,17 @@ function reportParksAtQuit(sessions, report) {
|
|
|
11810
11853
|
].join(" ")
|
|
11811
11854
|
);
|
|
11812
11855
|
}
|
|
11856
|
+
function reportSkippedWhileQuitting(context, requested) {
|
|
11857
|
+
context.report?.(
|
|
11858
|
+
[
|
|
11859
|
+
`trigger=${context.trigger}`,
|
|
11860
|
+
`mode=${MODE_OF_SHOW[requested]}`,
|
|
11861
|
+
`requested=${requested}`,
|
|
11862
|
+
...requesterFields(context),
|
|
11863
|
+
"applied=skipped+quitting"
|
|
11864
|
+
].join(" ")
|
|
11865
|
+
);
|
|
11866
|
+
}
|
|
11813
11867
|
function raiseWindow(window, show, context) {
|
|
11814
11868
|
if (show === "never") return;
|
|
11815
11869
|
const applied = [];
|
|
@@ -11848,6 +11902,17 @@ function readSecondLaunchRequest(input) {
|
|
|
11848
11902
|
};
|
|
11849
11903
|
}
|
|
11850
11904
|
function applySecondLaunch(request, target2) {
|
|
11905
|
+
if (target2.quitting) {
|
|
11906
|
+
reportSkippedWhileQuitting(
|
|
11907
|
+
{
|
|
11908
|
+
trigger: "second-instance",
|
|
11909
|
+
requester: request.requester ?? void 0,
|
|
11910
|
+
report: target2.report
|
|
11911
|
+
},
|
|
11912
|
+
request.show
|
|
11913
|
+
);
|
|
11914
|
+
return;
|
|
11915
|
+
}
|
|
11851
11916
|
if (request.session !== null) {
|
|
11852
11917
|
if (target2.openConversation) {
|
|
11853
11918
|
target2.openConversation(request.session, request);
|
|
@@ -12092,6 +12157,23 @@ class BackendInstaller {
|
|
|
12092
12157
|
* and never resolves at all.
|
|
12093
12158
|
*/
|
|
12094
12159
|
settleUserDecision = null;
|
|
12160
|
+
/**
|
|
12161
|
+
* What to tell the app when THIS window's question cancels a running quit.
|
|
12162
|
+
*
|
|
12163
|
+
* WHY THE INSTALLER CARRIES IT AND `index.ts` OWNS IT (round-1 review,
|
|
12164
|
+
* F-1). The declined "Quit without setup?" - `cancelId: 0`, the default -
|
|
12165
|
+
* lets a quit abort and leaves the process serving, which means any quit
|
|
12166
|
+
* that was in flight is now CANCELLED and the app must stop claiming
|
|
12167
|
+
* otherwise: without a release, `index.ts`'s quit state stays set and every
|
|
12168
|
+
* later second launch and Dock click is refused for the process's life
|
|
12169
|
+
* although the app is running normally. The dialog is the ONE cancellation
|
|
12170
|
+
* a running quit has (see `../quit-state` for the sweep); this module never
|
|
12171
|
+
* reaches for the app's state itself, so the installer stays drivable in a
|
|
12172
|
+
* test and the single release site stays greppable. Optional because the
|
|
12173
|
+
* harness constructs installers with no app around them, and a release that
|
|
12174
|
+
* fires where no quit exists clears an already-false state.
|
|
12175
|
+
*/
|
|
12176
|
+
onQuitCancelled;
|
|
12095
12177
|
/*
|
|
12096
12178
|
* The last phase announced to the setup window, and whether a failure is
|
|
12097
12179
|
* currently on screen with nobody's answer yet.
|
|
@@ -12203,8 +12285,14 @@ ${error instanceof Error ? error.message : String(error ?? "")}`;
|
|
|
12203
12285
|
}
|
|
12204
12286
|
/**
|
|
12205
12287
|
* Constructor
|
|
12288
|
+
*
|
|
12289
|
+
* `options.onQuitCancelled` is `index.ts`'s one release for the app's quit
|
|
12290
|
+
* state (see the field's own note); it is handed in rather than imported so
|
|
12291
|
+
* this module never depends on the app's lifecycle and its test can drive
|
|
12292
|
+
* the declined answer with a spy.
|
|
12206
12293
|
*/
|
|
12207
|
-
constructor() {
|
|
12294
|
+
constructor(options = {}) {
|
|
12295
|
+
this.onQuitCancelled = options.onQuitCancelled;
|
|
12208
12296
|
this.venvPath = managedVenvPath({
|
|
12209
12297
|
platform: process.platform,
|
|
12210
12298
|
home: electron.app.getPath("home"),
|
|
@@ -12851,6 +12939,7 @@ ${result.stdout}`,
|
|
|
12851
12939
|
"Setup quit declined from the setup window",
|
|
12852
12940
|
LogFileType.INSTALLER
|
|
12853
12941
|
);
|
|
12942
|
+
this.onQuitCancelled?.();
|
|
12854
12943
|
return;
|
|
12855
12944
|
}
|
|
12856
12945
|
this.attemptCancelled = inFlight;
|
|
@@ -32512,8 +32601,8 @@ function createMiniView(options) {
|
|
|
32512
32601
|
backgroundThrottling: false,
|
|
32513
32602
|
/*
|
|
32514
32603
|
* The argv the preload reads SYNCHRONOUSLY, and both entries are
|
|
32515
|
-
* deliberate: the chrome facts because the keycap's spelling (
|
|
32516
|
-
* against Ctrl+Alt) is a first-frame fact with no IPC round trip to
|
|
32604
|
+
* deliberate: the chrome facts because the keycap's spelling (⌘⌥⇧
|
|
32605
|
+
* against Ctrl+Alt+Shift) is a first-frame fact with no IPC round trip to
|
|
32517
32606
|
* wait for — the main window composes the same entry through
|
|
32518
32607
|
* `windowChromeArgumentFor` — and an EXPLICIT telemetry `off` because
|
|
32519
32608
|
* this window mounts no telemetry surface at all (§D.1), and the
|
|
@@ -32613,6 +32702,18 @@ function rememberPickedDirectory(kind, filePaths, directoryPicked = false) {
|
|
|
32613
32702
|
if (!first) return;
|
|
32614
32703
|
lastPickedDirectory.set(kind, directoryPicked ? first : path$1.dirname(first));
|
|
32615
32704
|
}
|
|
32705
|
+
function createQuitState() {
|
|
32706
|
+
let quitting = false;
|
|
32707
|
+
return {
|
|
32708
|
+
begin: () => {
|
|
32709
|
+
quitting = true;
|
|
32710
|
+
},
|
|
32711
|
+
cancel: () => {
|
|
32712
|
+
quitting = false;
|
|
32713
|
+
},
|
|
32714
|
+
isQuitting: () => quitting
|
|
32715
|
+
};
|
|
32716
|
+
}
|
|
32616
32717
|
function titlebarOptions(platform, chrome) {
|
|
32617
32718
|
if (platform === "darwin") {
|
|
32618
32719
|
return { titleBarStyle: "hidden" };
|
|
@@ -32803,10 +32904,10 @@ async function waitForFleetIdle(input) {
|
|
|
32803
32904
|
fleet: (await input.readRoster())?.length ?? 0
|
|
32804
32905
|
};
|
|
32805
32906
|
}
|
|
32806
|
-
function fleetDrainRefusalSentence(outcome
|
|
32907
|
+
function fleetDrainRefusalSentence(outcome) {
|
|
32807
32908
|
const minutes = Math.max(1, Math.round(outcome.waitedMs / 6e4));
|
|
32808
32909
|
const waited = `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
32809
|
-
const closing =
|
|
32910
|
+
const closing = "Nothing was installed and the server keeps running the build it loaded; the app will offer this update again.";
|
|
32810
32911
|
if (outcome.because === "unknown") {
|
|
32811
32912
|
const lead2 = outcome.credentialsRefused ? "The server refused this app's credentials, so the app could not read which sessions are running on this machine." : "The app could not read which sessions are running on this machine, so it did not update the server.";
|
|
32812
32913
|
return `${lead2}
|
|
@@ -32876,7 +32977,10 @@ async function reengageDisplacedSessions(input) {
|
|
|
32876
32977
|
const finalRead = await input.readRoster();
|
|
32877
32978
|
if (finalRead !== null) after = finalRead;
|
|
32878
32979
|
const displaced = displacedSessions(input.before, after);
|
|
32879
|
-
const
|
|
32980
|
+
const stillLiveAtEnd = stillLiveIn(finalRead) ?? stillLive;
|
|
32981
|
+
const stillResident = snapshot2.filter(
|
|
32982
|
+
(row) => stillLiveAtEnd.has(row.sessionId)
|
|
32983
|
+
);
|
|
32880
32984
|
const engaged = [];
|
|
32881
32985
|
const failed = [];
|
|
32882
32986
|
for (const row of displaced) {
|
|
@@ -34179,15 +34283,17 @@ class UpdateService {
|
|
|
34179
34283
|
*/
|
|
34180
34284
|
installPreflightInFlight = false;
|
|
34181
34285
|
/**
|
|
34182
|
-
* How long
|
|
34183
|
-
* re-reads it.
|
|
34286
|
+
* How long the rebuild install leg may hold back for the fleet, and how often
|
|
34287
|
+
* it re-reads it.
|
|
34184
34288
|
*
|
|
34185
|
-
* FIELDS rather than the module's constants read in place, because
|
|
34186
|
-
*
|
|
34187
|
-
*
|
|
34188
|
-
*
|
|
34189
|
-
*
|
|
34190
|
-
*
|
|
34289
|
+
* FIELDS rather than the module's constants read in place, because the wait has
|
|
34290
|
+
* to be drivable in milliseconds instead of ten minutes
|
|
34291
|
+
* (`scripts/update-robustness.test.mjs`, the same lever `waitForBackendVersion`
|
|
34292
|
+
* and the install budgets already are). The values they start at are the host
|
|
34293
|
+
* tool's own, in `backend/fleet-drain.ts`, where the reasoning for the ten
|
|
34294
|
+
* minutes lives - and where the module head records that the press reaching
|
|
34295
|
+
* this pair is now only the REBUILD route's install leg (the operator's
|
|
34296
|
+
* directive removed the restart-leg drains).
|
|
34191
34297
|
*/
|
|
34192
34298
|
fleetDrainBudgetMs = FLEET_DRAIN_BUDGET_MS;
|
|
34193
34299
|
fleetDrainPollMs = FLEET_DRAIN_POLL_MS;
|
|
@@ -34216,13 +34322,17 @@ class UpdateService {
|
|
|
34216
34322
|
sessionEngageBeatMs = SESSION_ENGAGE_BEAT_MS;
|
|
34217
34323
|
sessionEngageHoldMs = SESSION_ENGAGE_HOLD_MS;
|
|
34218
34324
|
/**
|
|
34219
|
-
* How long the press IN FLIGHT has already spent waiting for the fleet.
|
|
34325
|
+
* How long the rebuild press IN FLIGHT has already spent waiting for the fleet.
|
|
34220
34326
|
*
|
|
34221
|
-
* The budget above
|
|
34222
|
-
*
|
|
34223
|
-
* restart - so a per-drain budget
|
|
34224
|
-
*
|
|
34225
|
-
*
|
|
34327
|
+
* The budget above belongs to the PRESS, not to each drain (review round 1,
|
|
34328
|
+
* m2): when the restart legs still drained, a rebuild press drained twice -
|
|
34329
|
+
* once before the install and once before the restart - so a per-drain budget
|
|
34330
|
+
* let one press hold the button for twenty minutes while the panel promised
|
|
34331
|
+
* ten. The restart-leg drains are gone (2026-09-29 directive), so the ledger
|
|
34332
|
+
* now carries at most one leg's spend; it is kept because the promise the
|
|
34333
|
+
* draining copy makes is about the press, and because it is the seam the wait
|
|
34334
|
+
* is driven through. Reset at the top of every press, in `updateBackend`,
|
|
34335
|
+
* because the guarantee is about one press.
|
|
34226
34336
|
*/
|
|
34227
34337
|
fleetDrainSpentMs = 0;
|
|
34228
34338
|
/**
|
|
@@ -36980,13 +37090,16 @@ ${heal.removed.join("\n")}`,
|
|
|
36980
37090
|
* publishes a generation and restarts a daemon. It is the managed global
|
|
36981
37091
|
* arm's own wording, aimed at this arm's mechanism.
|
|
36982
37092
|
*
|
|
36983
|
-
* AND IT NO LONGER PROMISES A DROPPED TURN
|
|
36984
|
-
*
|
|
36985
|
-
*
|
|
36986
|
-
*
|
|
36987
|
-
*
|
|
37093
|
+
* AND IT NO LONGER PROMISES A DROPPED TURN - AND NO LONGER PRICES A WAIT. It
|
|
37094
|
+
* did both at different times, because it described what the press used to
|
|
37095
|
+
* do; the operator's directive of 2026-09-29 removed the fleet wait from the
|
|
37096
|
+
* restart legs ("we don't need to wait for all sessions to drain and turn
|
|
37097
|
+
* over... on idle they should switch over"), so the honest consequence names
|
|
37098
|
+
* the sequence, the promised absence of dropped work, and the fleet effect
|
|
37099
|
+
* that remains - sessions still working move onto the new build when they
|
|
37100
|
+
* next stop or go idle - with the cost stated as the time it takes.
|
|
36988
37101
|
*/
|
|
36989
|
-
remedy: "The app publishes the new build beside the one the server is using
|
|
37102
|
+
remedy: "The app publishes the new build beside the one the server is using and then moves the server onto it, so nothing in flight is cut off. Sessions that are still working move onto the new build when they next stop or go idle. This can take a minute or two.",
|
|
36990
37103
|
detail: `The app started this server itself (${startupMode}).`,
|
|
36991
37104
|
sourceBuild: false,
|
|
36992
37105
|
/*
|
|
@@ -37660,15 +37773,19 @@ ${heal.removed.join("\n")}`,
|
|
|
37660
37773
|
return this.backendService?.servingInstall().owned.owned ?? false;
|
|
37661
37774
|
}
|
|
37662
37775
|
/**
|
|
37663
|
-
* Wait for the fleet this app can see to go idle, or refuse the
|
|
37776
|
+
* Wait for the fleet this app can see to go idle, or refuse the rebuild.
|
|
37664
37777
|
*
|
|
37665
|
-
* THE ONE GATE
|
|
37666
|
-
*
|
|
37667
|
-
*
|
|
37668
|
-
*
|
|
37669
|
-
*
|
|
37670
|
-
* drain
|
|
37671
|
-
*
|
|
37778
|
+
* THE ONE REMAINING GATE, AND IT GUARDS THE ONE ROUTE THAT CAN CUT A TURN. This
|
|
37779
|
+
* used to stand in front of every restart and every in-place install. The
|
|
37780
|
+
* operator's directive of 2026-09-29 removed it from the RESTART legs - a
|
|
37781
|
+
* daemon bounce cuts no turns, because session runtimes are detached and
|
|
37782
|
+
* converge onto the new build at their own next idle (see the module head in
|
|
37783
|
+
* `backend/fleet-drain.ts`) - so what is left is the route it still has to
|
|
37784
|
+
* guard: the checkout REBUILD's install leg, which rewrites a tree a live
|
|
37785
|
+
* runtime is reading (`update-install.ts`). There the operator's rule stands:
|
|
37786
|
+
* nothing kills runtimes en masse, so the app waits for the fleet to drain
|
|
37787
|
+
* before the rebuild starts, and REFUSES with a remedy at the end of its
|
|
37788
|
+
* budget rather than cutting off a turn on a timer.
|
|
37672
37789
|
*
|
|
37673
37790
|
* WHY THE MANAGER'S OWN READERS. `servingWorkState` is the app's existing
|
|
37674
37791
|
* busy signal (see `servingWorkStateFromSessions`) and `servingSessionFleet`
|
|
@@ -37683,7 +37800,7 @@ ${heal.removed.join("\n")}`,
|
|
|
37683
37800
|
* when the update was refused and the caller must not proceed
|
|
37684
37801
|
*/
|
|
37685
37802
|
async drainFleetForUpdate(input) {
|
|
37686
|
-
const { backend
|
|
37803
|
+
const { backend } = input;
|
|
37687
37804
|
const spentMs = this.fleetDrainSpentMs;
|
|
37688
37805
|
const remainingMs = Math.max(0, this.fleetDrainBudgetMs - spentMs);
|
|
37689
37806
|
const outcome = await waitForFleetIdle({
|
|
@@ -37710,7 +37827,7 @@ ${heal.removed.join("\n")}`,
|
|
|
37710
37827
|
waitedMs: spentMs + elapsedMs
|
|
37711
37828
|
});
|
|
37712
37829
|
logger.info(
|
|
37713
|
-
`Update waiting for the fleet to drain before
|
|
37830
|
+
`Update waiting for the fleet to drain before the rebuild may start (${Math.round(elapsedMs / 1e3)}s so far)`,
|
|
37714
37831
|
LogFileType.UPDATE_SERVICE
|
|
37715
37832
|
);
|
|
37716
37833
|
}
|
|
@@ -37718,19 +37835,16 @@ ${heal.removed.join("\n")}`,
|
|
|
37718
37835
|
this.fleetDrainSpentMs = spentMs + outcome.waitedMs;
|
|
37719
37836
|
if (outcome.kind === "drained") {
|
|
37720
37837
|
logger.info(
|
|
37721
|
-
`The fleet is idle (${outcome.fleet} session(s) on the roster, ${outcome.waitedMs}ms waited); the
|
|
37838
|
+
`The fleet is idle (${outcome.fleet} session(s) on the roster, ${outcome.waitedMs}ms waited); the rebuild may start`,
|
|
37722
37839
|
LogFileType.UPDATE_SERVICE
|
|
37723
37840
|
);
|
|
37724
37841
|
return true;
|
|
37725
37842
|
}
|
|
37726
|
-
const message = fleetDrainRefusalSentence(
|
|
37727
|
-
outcome,
|
|
37728
|
-
input.installLanded === true
|
|
37729
|
-
);
|
|
37843
|
+
const message = fleetDrainRefusalSentence(outcome);
|
|
37730
37844
|
const command = input.command ?? null;
|
|
37731
37845
|
const pressWaitedMs = spentMs + outcome.waitedMs;
|
|
37732
37846
|
logger.warn(
|
|
37733
|
-
`Refusing to
|
|
37847
|
+
`Refusing to install: the fleet did not drain in ${pressWaitedMs}ms (${outcome.because}, ${outcome.busy.length} mid-turn, this leg spent ${outcome.waitedMs}ms). ${message}${command ? ` By hand: ${command}` : ""}`,
|
|
37734
37848
|
LogFileType.UPDATE_SERVICE
|
|
37735
37849
|
);
|
|
37736
37850
|
this.sendToRenderer("backend-update-error", {
|
|
@@ -37747,17 +37861,7 @@ ${heal.removed.join("\n")}`,
|
|
|
37747
37861
|
because: outcome.because,
|
|
37748
37862
|
waitedMs: pressWaitedMs,
|
|
37749
37863
|
command,
|
|
37750
|
-
credentialsRefused: outcome.credentialsRefused === true
|
|
37751
|
-
/*
|
|
37752
|
-
* WHICH REFUSAL THIS IS (design round 2, D6). The heading is the reader's
|
|
37753
|
-
* takeaway from a panel they have been looking at for ten minutes, and the
|
|
37754
|
-
* three refusal sites are not the same event: the install leg's refusal left
|
|
37755
|
-
* nothing on disk, while the two restart-leg refusals happen AFTER the build
|
|
37756
|
-
* landed. "The update didn't start" is false on the second pair - the
|
|
37757
|
-
* producer's own doc for `installLanded` says so - so the fact travels with
|
|
37758
|
-
* the report and the panel keys its heading on it.
|
|
37759
|
-
*/
|
|
37760
|
-
installLanded: input.installLanded === true
|
|
37864
|
+
credentialsRefused: outcome.credentialsRefused === true
|
|
37761
37865
|
}
|
|
37762
37866
|
});
|
|
37763
37867
|
return false;
|
|
@@ -37766,15 +37870,22 @@ ${heal.removed.join("\n")}`,
|
|
|
37766
37870
|
* Put back the runtimes a restart displaced, and say what came back.
|
|
37767
37871
|
*
|
|
37768
37872
|
* Step 5 of the host tool's own order (`~/tools/lop-fleet-update`): the app
|
|
37769
|
-
* snapshots the fleet,
|
|
37770
|
-
*
|
|
37771
|
-
*
|
|
37772
|
-
*
|
|
37773
|
-
*
|
|
37774
|
-
* BEST EFFORT AND NEVER A BLOCKER:
|
|
37775
|
-
*
|
|
37776
|
-
*
|
|
37777
|
-
*
|
|
37873
|
+
* snapshots the fleet, moves the server, and then re-engages what the move
|
|
37874
|
+
* displaced - the unwatched `daemon`-kind sessions in particular, which nothing
|
|
37875
|
+
* else revives. `reengageDisplacedSessions` owns the retire wait and the
|
|
37876
|
+
* ordering rules.
|
|
37877
|
+
*
|
|
37878
|
+
* BEST EFFORT AND NEVER A BLOCKER: a displace list that will not come back is a
|
|
37879
|
+
* logged fact rather than a failed update. That is deliberate - a `warm` the
|
|
37880
|
+
* daemon refuses must not turn a landed update into an error panel.
|
|
37881
|
+
*
|
|
37882
|
+
* THE RESULT IS RETURNED FOR THE COMPLETION'S COUNT (2026-09-29): the caller
|
|
37883
|
+
* reads `stillResident` - the pre-swap runtimes still resident in the freshest
|
|
37884
|
+
* read at the wait's end, which in the ordinary flow are the sessions still on
|
|
37885
|
+
* the old build - into `sessionsOnOldBuild`. It is a liveness reading rather
|
|
37886
|
+
* than a build read (the field's own docblock names the one narrow over-count).
|
|
37887
|
+
* A failure here answers null and the count is reported as not measured, so
|
|
37888
|
+
* the notice degrades to the numberless sentence rather than inventing a zero.
|
|
37778
37889
|
*/
|
|
37779
37890
|
async reengageFleetAfterRestart(backend, before) {
|
|
37780
37891
|
try {
|
|
@@ -37796,7 +37907,7 @@ ${heal.removed.join("\n")}`,
|
|
|
37796
37907
|
LogFileType.UPDATE_SERVICE
|
|
37797
37908
|
);
|
|
37798
37909
|
}
|
|
37799
|
-
return;
|
|
37910
|
+
return result;
|
|
37800
37911
|
}
|
|
37801
37912
|
if (result.failed.length > 0) {
|
|
37802
37913
|
logger.warn(
|
|
@@ -37804,11 +37915,13 @@ ${heal.removed.join("\n")}`,
|
|
|
37804
37915
|
LogFileType.UPDATE_SERVICE
|
|
37805
37916
|
);
|
|
37806
37917
|
}
|
|
37918
|
+
return result;
|
|
37807
37919
|
} catch (error) {
|
|
37808
37920
|
logger.warn(
|
|
37809
37921
|
`Could not re-engage the sessions a restart displaced: ${error instanceof Error ? error.message : String(error)}`,
|
|
37810
37922
|
LogFileType.UPDATE_SERVICE
|
|
37811
37923
|
);
|
|
37924
|
+
return null;
|
|
37812
37925
|
}
|
|
37813
37926
|
}
|
|
37814
37927
|
/**
|
|
@@ -37857,9 +37970,11 @@ ${heal.removed.join("\n")}`,
|
|
|
37857
37970
|
*
|
|
37858
37971
|
* NOT `sessions.message`, deliberately: a message would admit a turn in every
|
|
37859
37972
|
* conversation this machine holds, which is work and spend the user did not ask
|
|
37860
|
-
* for
|
|
37861
|
-
*
|
|
37862
|
-
* server moved
|
|
37973
|
+
* for - and since the operator's directive removed the restart-leg drains
|
|
37974
|
+
* (2026-09-29), a re-engaged session may legitimately have been mid-turn when
|
|
37975
|
+
* the server moved: a daemon bounce cuts no turns, and the session's own turn
|
|
37976
|
+
* kept running in its detached runtime. This call starts a runtime; it never
|
|
37977
|
+
* touches a turn.
|
|
37863
37978
|
*/
|
|
37864
37979
|
async engageSessionRuntime(backend, row) {
|
|
37865
37980
|
const relay = backend.getStreamRelay();
|
|
@@ -38318,8 +38433,7 @@ ${heal.removed.join("\n")}`,
|
|
|
38318
38433
|
const fleetBeforeInstall = rebuildRoute ? await this.readFleetSnapshot(backend) : null;
|
|
38319
38434
|
if (rebuildRoute && !await this.drainFleetForUpdate({
|
|
38320
38435
|
backend,
|
|
38321
|
-
command: freshPlan.updateCommand ?? null
|
|
38322
|
-
what: "install"
|
|
38436
|
+
command: freshPlan.updateCommand ?? null
|
|
38323
38437
|
})) {
|
|
38324
38438
|
return false;
|
|
38325
38439
|
}
|
|
@@ -38438,23 +38552,6 @@ ${heal.removed.join("\n")}`,
|
|
|
38438
38552
|
});
|
|
38439
38553
|
return true;
|
|
38440
38554
|
}
|
|
38441
|
-
if (!await this.drainFleetForUpdate({
|
|
38442
|
-
backend,
|
|
38443
|
-
command: freshPlan.updateCommand ?? null,
|
|
38444
|
-
what: "restart",
|
|
38445
|
-
/*
|
|
38446
|
-
* A press with nothing left to install has no install to report as
|
|
38447
|
-
* landed, and saying one was would be the one false thing in the
|
|
38448
|
-
* refusal.
|
|
38449
|
-
*/
|
|
38450
|
-
installLanded: !installAlreadyCurrent
|
|
38451
|
-
})) {
|
|
38452
|
-
logger.info(
|
|
38453
|
-
installAlreadyCurrent ? "Nothing was left to install; the restart was refused because the fleet did not drain. The daemon keeps serving the build it loaded." : "The install landed; the restart was refused because the fleet did not drain. The daemon keeps serving the build it loaded.",
|
|
38454
|
-
LogFileType.UPDATE_SERVICE
|
|
38455
|
-
);
|
|
38456
|
-
return false;
|
|
38457
|
-
}
|
|
38458
38555
|
logger.info(
|
|
38459
38556
|
"Restarting backend service onto the updated install...",
|
|
38460
38557
|
LogFileType.UPDATE_SERVICE
|
|
@@ -38518,13 +38615,12 @@ ${heal.removed.join("\n")}`,
|
|
|
38518
38615
|
fleetBeforeInstall,
|
|
38519
38616
|
fleetBeforeRestart
|
|
38520
38617
|
);
|
|
38521
|
-
|
|
38522
|
-
await this.reengageFleetAfterRestart(backend, reengageSnapshot);
|
|
38523
|
-
}
|
|
38618
|
+
const reengage = reengageSnapshot !== null ? await this.reengageFleetAfterRestart(backend, reengageSnapshot) : null;
|
|
38524
38619
|
this.sendToRenderer("backend-update-completed", {
|
|
38525
38620
|
installVersion: after,
|
|
38526
38621
|
runningVersion: reported,
|
|
38527
|
-
restarted: true
|
|
38622
|
+
restarted: true,
|
|
38623
|
+
sessionsOnOldBuild: reengage?.stillResident.length ?? null
|
|
38528
38624
|
});
|
|
38529
38625
|
return true;
|
|
38530
38626
|
}
|
|
@@ -38873,14 +38969,6 @@ ${reason}` : ""}`,
|
|
|
38873
38969
|
return true;
|
|
38874
38970
|
}
|
|
38875
38971
|
const fleetAfterPublish = await this.readFleetSnapshot(backend);
|
|
38876
|
-
if (!await this.drainFleetForUpdate({
|
|
38877
|
-
backend,
|
|
38878
|
-
command: null,
|
|
38879
|
-
what: "restart",
|
|
38880
|
-
installLanded: outcome.replaced
|
|
38881
|
-
})) {
|
|
38882
|
-
return false;
|
|
38883
|
-
}
|
|
38884
38972
|
logger.info(
|
|
38885
38973
|
"Restarting backend service onto the published environment...",
|
|
38886
38974
|
LogFileType.UPDATE_SERVICE
|
|
@@ -38969,13 +39057,12 @@ ${reason}` : ""}`,
|
|
|
38969
39057
|
fleetAfterPublish,
|
|
38970
39058
|
fleetBeforeRestart
|
|
38971
39059
|
);
|
|
38972
|
-
|
|
38973
|
-
await this.reengageFleetAfterRestart(backend, reengageSnapshot);
|
|
38974
|
-
}
|
|
39060
|
+
const reengage = reengageSnapshot !== null ? await this.reengageFleetAfterRestart(backend, reengageSnapshot) : null;
|
|
38975
39061
|
this.sendToRenderer("backend-update-completed", {
|
|
38976
39062
|
installVersion,
|
|
38977
39063
|
runningVersion: running,
|
|
38978
|
-
restarted: true
|
|
39064
|
+
restarted: true,
|
|
39065
|
+
sessionsOnOldBuild: reengage?.stillResident.length ?? null
|
|
38979
39066
|
});
|
|
38980
39067
|
return true;
|
|
38981
39068
|
}
|
|
@@ -40166,7 +40253,12 @@ const userShellPath = createUserShellPath({
|
|
|
40166
40253
|
log: (message) => logger.info(message, LogFileType.BACKEND)
|
|
40167
40254
|
});
|
|
40168
40255
|
const backendService = new BackendServiceManager({ userShellPath });
|
|
40169
|
-
const
|
|
40256
|
+
const quitState = createQuitState();
|
|
40257
|
+
const backendInstaller = new BackendInstaller({
|
|
40258
|
+
// The installer's one route back from a cancelled quit: the declined dialog
|
|
40259
|
+
// answer (`./quit-state` owns why there is exactly one such site).
|
|
40260
|
+
onQuitCancelled: () => quitState.cancel()
|
|
40261
|
+
});
|
|
40170
40262
|
const reportBackendFailure = (message, fileType) => {
|
|
40171
40263
|
if (backendService.isShuttingDown()) {
|
|
40172
40264
|
logger.error(
|
|
@@ -40380,6 +40472,16 @@ if (!gotTheLock) {
|
|
|
40380
40472
|
}),
|
|
40381
40473
|
{
|
|
40382
40474
|
window: mainWindow,
|
|
40475
|
+
/*
|
|
40476
|
+
* Read PER REQUEST rather than captured once: this handler outlives every
|
|
40477
|
+
* window, and the state is LIVE — set at each quit's first `before-quit`
|
|
40478
|
+
* entry, released when the setup dialog declines to stop a run — so a
|
|
40479
|
+
* request that arrives during a quit is refused instead of answered with
|
|
40480
|
+
* a window the shutdown would take down, and a request after a CANCELLED
|
|
40481
|
+
* quit is answered normally (`./quit-state` owns the transitions;
|
|
40482
|
+
* `window-raise.ts` owns the refusal and its line).
|
|
40483
|
+
*/
|
|
40484
|
+
quitting: quitState.isQuitting(),
|
|
40383
40485
|
openConversation: openConversationInWindow ? (session, request) => openConversationInWindow?.(
|
|
40384
40486
|
session,
|
|
40385
40487
|
secondInstanceRequest(request)
|
|
@@ -40559,7 +40661,10 @@ electron.app.whenReady().then(async () => {
|
|
|
40559
40661
|
});
|
|
40560
40662
|
return "raised the window";
|
|
40561
40663
|
}
|
|
40562
|
-
setupMainWindowWithUpdateService(
|
|
40664
|
+
setupMainWindowWithUpdateService(null, false, {
|
|
40665
|
+
show: windowLaunch.show,
|
|
40666
|
+
trigger: "viewer-focus"
|
|
40667
|
+
});
|
|
40563
40668
|
return "opened a window";
|
|
40564
40669
|
}
|
|
40565
40670
|
},
|
|
@@ -40609,7 +40714,7 @@ electron.app.whenReady().then(async () => {
|
|
|
40609
40714
|
* this feature's slice for a value that is a launch fact (argv, the
|
|
40610
40715
|
* launch env, the persisted file) and cannot differ between the two
|
|
40611
40716
|
* calls. The mini view's visible consumer of it is the platform
|
|
40612
|
-
* half: the header's keycap spells
|
|
40717
|
+
* half: the header's keycap spells ⌘⌥⇧Space against Ctrl+Alt+Shift+Space
|
|
40613
40718
|
* from exactly this entry.
|
|
40614
40719
|
*/
|
|
40615
40720
|
chromeMode: resolveLaunchWindowChrome({
|
|
@@ -41151,6 +41256,10 @@ electron.app.whenReady().then(async () => {
|
|
|
41151
41256
|
});
|
|
41152
41257
|
}
|
|
41153
41258
|
function setupMainWindowWithUpdateService(initialSession = null, openCatalogue = false, request = ownLaunchRequest()) {
|
|
41259
|
+
if (quitState.isQuitting()) {
|
|
41260
|
+
reportSkippedWhileQuitting(request, request.show);
|
|
41261
|
+
return;
|
|
41262
|
+
}
|
|
41154
41263
|
const parked = initialSession === null && !openCatalogue ? parkedLaunches[0] : void 0;
|
|
41155
41264
|
mainWindow = createWindow(
|
|
41156
41265
|
parked?.session ?? initialSession,
|
|
@@ -41314,6 +41423,10 @@ electron.app.whenReady().then(async () => {
|
|
|
41314
41423
|
});
|
|
41315
41424
|
return;
|
|
41316
41425
|
}
|
|
41426
|
+
if (quitState.isQuitting()) {
|
|
41427
|
+
reportSkippedWhileQuitting(request, request.show);
|
|
41428
|
+
return;
|
|
41429
|
+
}
|
|
41317
41430
|
if (!canCreateWindowFor(request.show)) {
|
|
41318
41431
|
if (sessionId2 !== null) parkLaunch(sessionId2, request);
|
|
41319
41432
|
return;
|
|
@@ -41328,9 +41441,22 @@ electron.app.whenReady().then(async () => {
|
|
|
41328
41441
|
setupMainWindowWithUpdateService(launchSession, launchCatalogue);
|
|
41329
41442
|
electron.app.on("activate", () => {
|
|
41330
41443
|
if (electron.BrowserWindow.getAllWindows().length === 0) {
|
|
41444
|
+
if (quitState.isQuitting()) {
|
|
41445
|
+
reportSkippedWhileQuitting(
|
|
41446
|
+
{ trigger: "activate", report: reportRaise },
|
|
41447
|
+
OPERATOR_SHOW
|
|
41448
|
+
);
|
|
41449
|
+
return;
|
|
41450
|
+
}
|
|
41331
41451
|
setupMainWindowWithUpdateService(null, false, {
|
|
41332
41452
|
show: OPERATOR_SHOW,
|
|
41333
|
-
|
|
41453
|
+
/*
|
|
41454
|
+
* The request names itself on its raise line. It used to present as
|
|
41455
|
+
* `initial-present` — this process's own launch — which is what a Dock
|
|
41456
|
+
* click is not, and the log's whole job is attribution; the refusal
|
|
41457
|
+
* above is the same request and must carry the same name.
|
|
41458
|
+
*/
|
|
41459
|
+
trigger: "activate"
|
|
41334
41460
|
});
|
|
41335
41461
|
}
|
|
41336
41462
|
});
|
|
@@ -41410,6 +41536,7 @@ const holdQuitForSessionCookieSnapshot = createSessionCookieQuitHold({
|
|
|
41410
41536
|
log: (message) => logger.warn(message, LogFileType.BACKEND)
|
|
41411
41537
|
});
|
|
41412
41538
|
electron.app.on("before-quit", async (event) => {
|
|
41539
|
+
quitState.begin();
|
|
41413
41540
|
if (await holdQuitForSessionCookieSnapshot(event)) return;
|
|
41414
41541
|
logger.info("App is about to quit", LogFileType.BACKEND);
|
|
41415
41542
|
if (parkedLaunches.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as o,c as b,g as v,k as O,h as P,j as p,l as w,m as A,n as x,t as c,o as N}from"./_baseUniq-
|
|
1
|
+
import{e as o,c as b,g as v,k as O,h as P,j as p,l as w,m as A,n as x,t as c,o as N}from"./_baseUniq-cZFY6WR-.js";import{as as g,aa as y,at as E,au as F,av as M,aw as I,ax as _,ay as $,az as B,aA as T}from"./mermaid.core-Dol6F2oY.js";var S=/\s/;function z(n){for(var r=n.length;r--&&S.test(n.charAt(r)););return r}var G=/^\s+/;function H(n){return n&&n.slice(0,z(n)+1).replace(G,"")}var m=NaN,L=/^[-+]0x[0-9a-f]+$/i,R=/^0b[01]+$/i,q=/^0o[0-7]+$/i,C=parseInt;function K(n){if(typeof n=="number")return n;if(o(n))return m;if(g(n)){var r=typeof n.valueOf=="function"?n.valueOf():n;n=g(r)?r+"":r}if(typeof n!="string")return n===0?n:+n;n=H(n);var t=R.test(n);return t||q.test(n)?C(n.slice(2),t?2:8):L.test(n)?m:+n}var W=1/0,X=17976931348623157e292;function Y(n){if(!n)return n===0?n:0;if(n=K(n),n===W||n===-1/0){var r=n<0?-1:1;return r*X}return n===n?n:0}function D(n){var r=Y(n),t=r%1;return r===r?t?r-t:r:0}function fn(n){var r=n==null?0:n.length;return r?b(n):[]}var l=Object.prototype,J=l.hasOwnProperty,dn=y(function(n,r){n=Object(n);var t=-1,e=r.length,a=e>2?r[2]:void 0;for(a&&E(r[0],r[1],a)&&(e=1);++t<e;)for(var f=r[t],i=F(f),s=-1,d=i.length;++s<d;){var u=i[s],h=n[u];(h===void 0||M(h,l[u])&&!J.call(n,u))&&(n[u]=f[u])}return n});function un(n){var r=n==null?0:n.length;return r?n[r-1]:void 0}function Q(n){return function(r,t,e){var a=Object(r);if(!I(r)){var f=v(t);r=O(r),t=function(s){return f(a[s],s,a)}}var i=n(r,t,e);return i>-1?a[f?r[i]:i]:void 0}}var U=Math.max;function Z(n,r,t){var e=n==null?0:n.length;if(!e)return-1;var a=t==null?0:D(t);return a<0&&(a=U(e+a,0)),P(n,v(r),a)}var hn=Q(Z);function V(n,r){var t=-1,e=I(n)?Array(n.length):[];return p(n,function(a,f,i){e[++t]=r(a,f,i)}),e}function gn(n,r){var t=_(n)?w:V;return t(n,v(r))}var j=Object.prototype,k=j.hasOwnProperty;function nn(n,r){return n!=null&&k.call(n,r)}function vn(n,r){return n!=null&&A(n,r,nn)}function rn(n,r){return n<r}function tn(n,r,t){for(var e=-1,a=n.length;++e<a;){var f=n[e],i=r(f);if(i!=null&&(s===void 0?i===i&&!o(i):t(i,s)))var s=i,d=f}return d}function mn(n){return n&&n.length?tn(n,$,rn):void 0}function an(n,r,t,e){if(!g(n))return n;r=x(r,n);for(var a=-1,f=r.length,i=f-1,s=n;s!=null&&++a<f;){var d=c(r[a]),u=t;if(d==="__proto__"||d==="constructor"||d==="prototype")return n;if(a!=i){var h=s[d];u=void 0,u===void 0&&(u=g(h)?h:B(r[a+1])?[]:{})}T(s,d,u),s=s[d]}return n}function on(n,r,t){for(var e=-1,a=r.length,f={};++e<a;){var i=r[e],s=N(n,i);t(s,i)&&an(f,x(i,n),s)}return f}export{rn as a,tn as b,V as c,on as d,mn as e,fn as f,hn as g,vn as h,dn as i,D as j,un as l,gn as m,Y as t};
|