@wrongstack/cli 0.296.4 → 0.297.0
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/dist/boot/dispatch-webui.d.ts +7 -0
- package/dist/boot/dispatch-webui.d.ts.map +1 -1
- package/dist/boot/launch-banner.d.ts +22 -0
- package/dist/boot/launch-banner.d.ts.map +1 -0
- package/dist/boot/launch-menu.d.ts.map +1 -1
- package/dist/boot/tui-settings-adapter.d.ts.map +1 -1
- package/dist/{chunk-OI7GWJDS.js → chunk-7JABKXET.js} +372 -10
- package/dist/chunk-7JABKXET.js.map +7 -0
- package/dist/{chunk-WY7KKOUK.js → chunk-JW75HY4F.js} +31 -10
- package/dist/chunk-JW75HY4F.js.map +7 -0
- package/dist/{chunk-Z7YGASQP.js → chunk-QZKWRNIP.js} +19 -18
- package/dist/chunk-QZKWRNIP.js.map +7 -0
- package/dist/{chunk-BQCAJ7FI.js → chunk-XTIXVJXP.js} +16 -3
- package/dist/chunk-XTIXVJXP.js.map +7 -0
- package/dist/{cli-main-TOAWVJDY.js → cli-main-GOY5YGVL.js} +25199 -25107
- package/dist/cli-main-GOY5YGVL.js.map +7 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/{execution-O7I5DYE6.js → execution-A4PGK4XV.js} +39 -9
- package/dist/execution-A4PGK4XV.js.map +7 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/fleet-statusline.d.ts.map +1 -1
- package/dist/goal-host.d.ts +1 -1
- package/dist/goal-host.d.ts.map +1 -1
- package/dist/{hq-JUYKUNJX.js → hq-GBPGXIR5.js} +2 -2
- package/dist/hq-publisher.d.ts +3 -2
- package/dist/hq-publisher.d.ts.map +1 -1
- package/dist/hq-server/types.d.ts +8 -0
- package/dist/hq-server/types.d.ts.map +1 -1
- package/dist/hq-server/ws.d.ts +61 -2
- package/dist/hq-server/ws.d.ts.map +1 -1
- package/dist/{hq-server-6AQ3BXZA.js → hq-server-YQUUMTPU.js} +2 -2
- package/dist/index.js +293 -26
- package/dist/index.js.map +4 -4
- package/dist/kanban-hq-sync.d.ts +13 -1
- package/dist/kanban-hq-sync.d.ts.map +1 -1
- package/dist/live-settings-input.d.ts +9 -0
- package/dist/live-settings-input.d.ts.map +1 -1
- package/dist/{mailbox-serve-2UWHEN3M.js → mailbox-serve-DBOOOOWZ.js} +50 -8
- package/dist/mailbox-serve-DBOOOOWZ.js.map +7 -0
- package/dist/{sdd-runtime-JG4EEKL6.js → sdd-runtime-AIJCJGWC.js} +2 -2
- package/dist/services/sdd/state.d.ts +3 -3
- package/dist/services/sdd/state.d.ts.map +1 -1
- package/dist/services/sdd/task-manager.d.ts.map +1 -1
- package/dist/session-stats.d.ts.map +1 -1
- package/dist/settings-menu.d.ts.map +1 -1
- package/dist/slash-commands/command-context.d.ts +2 -0
- package/dist/slash-commands/command-context.d.ts.map +1 -1
- package/dist/slash-commands/goal.d.ts +1 -1
- package/dist/slash-commands/goal.d.ts.map +1 -1
- package/dist/slash-commands/sdd.d.ts.map +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts.map +1 -1
- package/dist/webui-server/session-start-payload.d.ts +4 -0
- package/dist/webui-server/session-start-payload.d.ts.map +1 -1
- package/dist/{webui-server-ZF5KVGC5.js → webui-server-XKFUOKMJ.js} +155 -132
- package/dist/webui-server-XKFUOKMJ.js.map +7 -0
- package/dist/webui-server-options.d.ts +7 -0
- package/dist/webui-server-options.d.ts.map +1 -1
- package/dist/webui-server.d.ts.map +1 -1
- package/dist/wiring/command-host-state.d.ts.map +1 -1
- package/dist/wiring/hq-telemetry.d.ts +4 -3
- package/dist/wiring/hq-telemetry.d.ts.map +1 -1
- package/dist/wiring/lifecycle-plugins.d.ts +5 -8
- package/dist/wiring/lifecycle-plugins.d.ts.map +1 -1
- package/dist/wiring/metrics.d.ts +1 -1
- package/dist/wiring/metrics.d.ts.map +1 -1
- package/dist/wiring/runtime-lifecycle-deps.d.ts.map +1 -1
- package/dist/wiring/sage.d.ts.map +1 -1
- package/dist/wiring/sdd-handlers.d.ts.map +1 -1
- package/package.json +22 -22
- package/dist/chunk-BQCAJ7FI.js.map +0 -7
- package/dist/chunk-OI7GWJDS.js.map +0 -7
- package/dist/chunk-WY7KKOUK.js.map +0 -7
- package/dist/chunk-Z7YGASQP.js.map +0 -7
- package/dist/cli-main-TOAWVJDY.js.map +0 -7
- package/dist/execution-O7I5DYE6.js.map +0 -7
- package/dist/mailbox-serve-2UWHEN3M.js.map +0 -7
- package/dist/webui-server-ZF5KVGC5.js.map +0 -7
- /package/dist/{hq-JUYKUNJX.js.map → hq-GBPGXIR5.js.map} +0 -0
- /package/dist/{hq-server-6AQ3BXZA.js.map → hq-server-YQUUMTPU.js.map} +0 -0
- /package/dist/{sdd-runtime-JG4EEKL6.js.map → sdd-runtime-AIJCJGWC.js.map} +0 -0
|
@@ -72,6 +72,13 @@ export interface WebUIDispatchContext {
|
|
|
72
72
|
getAllSessions(): import('@wrongstack/core/coordination').AgentVirtualSession[];
|
|
73
73
|
loadSessionsFromDisk(): Promise<import('@wrongstack/core/coordination').AgentVirtualSession[]>;
|
|
74
74
|
} | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Pre-computed update info from the CLI's preflight version check.
|
|
77
|
+
* When present, surfaces (WebUI, SimpleUI) receive appVersion,
|
|
78
|
+
* latestVersion, and updateAvailable fields in their session.start
|
|
79
|
+
* payload to display an "update available" warning.
|
|
80
|
+
*/
|
|
81
|
+
updateInfo?: import('../webui-server/session-start-payload.js').BootUpdateInfo | undefined;
|
|
75
82
|
/** Per-task agent factory for the SDD wizard's multi-agent run. */
|
|
76
83
|
sddSubagentFactory?: import('@wrongstack/core/coordination').AgentFactory | undefined;
|
|
77
84
|
onKanbanDispatch?: ((description: string, opts?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-webui.d.ts","sourceRoot":"","sources":["../../src/boot/dispatch-webui.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dispatch-webui.d.ts","sourceRoot":"","sources":["../../src/boot/dispatch-webui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-boot launch banner — the WRONGSTACK brand mark + wordmark rendered
|
|
3
|
+
* as raw ANSI strings for the plain-terminal launch menu.
|
|
4
|
+
*
|
|
5
|
+
* This is a deliberate plain-string twin of the TUI banner
|
|
6
|
+
* (packages/tui/src/components/history/banner.tsx). Importing the TUI
|
|
7
|
+
* component here would drag ink+react into the pre-boot path — which may
|
|
8
|
+
* end up launching WebUI/HQ and never need them. When the TUI glyph
|
|
9
|
+
* tables or palette change, update these in the same commit.
|
|
10
|
+
*/
|
|
11
|
+
/** Exported so the menu can decide full vs compact by terminal width. */
|
|
12
|
+
export declare const WORDMARK_WIDTH: number;
|
|
13
|
+
/**
|
|
14
|
+
* Build the launch-screen banner as an array of pre-colored lines
|
|
15
|
+
* (no trailing newlines, no indent — the caller owns placement).
|
|
16
|
+
*
|
|
17
|
+
* Full art (mark + wordmark + tagline) when the terminal is wide enough;
|
|
18
|
+
* a one-line gradient fallback otherwise. Honors NO_COLOR / non-TTY by
|
|
19
|
+
* emitting plain text.
|
|
20
|
+
*/
|
|
21
|
+
export declare function launchBannerLines(columns: number, version?: string): string[];
|
|
22
|
+
//# sourceMappingURL=launch-banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-banner.d.ts","sourceRoot":"","sources":["../../src/boot/launch-banner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmDH,yEAAyE;AACzE,eAAO,MAAM,cAAc,QAAsD,CAAC;AAsElF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch-menu.d.ts","sourceRoot":"","sources":["../../src/boot/launch-menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"launch-menu.d.ts","sourceRoot":"","sources":["../../src/boot/launch-menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEtD,yEAAyE;AACzE,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAKD,QAAA,MAAM,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,MAAM,CAItE,CAAC;AAsBF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EACvC,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAuBT;AAuCD,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,mBAAmB,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,aAAa,CAAC,GAAG,SAAS,CAAC;CAC1D;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAyE7F;AAmVD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,gBAAgB,GACvB,MAAM,EAAE,CA2BV;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,GACvB,gBAAgB,GAAG,SAAS,CAe9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-settings-adapter.d.ts","sourceRoot":"","sources":["../../src/boot/tui-settings-adapter.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAU,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AASnE,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,qBAAqB,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAClG,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChE;AAYD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"tui-settings-adapter.d.ts","sourceRoot":"","sources":["../../src/boot/tui-settings-adapter.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAU,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AASnE,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,qBAAqB,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAClG,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChE;AAYD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,GAAG,eAAe,CAsgBlF"}
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
createHqPersistence,
|
|
20
20
|
HqAlertEngine,
|
|
21
|
-
HqCommandAuditLog,
|
|
22
21
|
HqBootstrapCodeStore,
|
|
22
|
+
HqCommandAuditLog,
|
|
23
23
|
mintHqCookieSecret as mintHqCookieSecret2,
|
|
24
24
|
mutateHqAuthFile as mutateHqAuthFile2,
|
|
25
25
|
toAlertMessage,
|
|
@@ -2391,7 +2391,11 @@ function writeHqLanEndpoints(write, handle, browserToken) {
|
|
|
2391
2391
|
// src/hq-server/ws.ts
|
|
2392
2392
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
2393
2393
|
import {
|
|
2394
|
+
HQ_BROWSER_PEER_RESUME_CLIENT_ID,
|
|
2394
2395
|
HQ_PROTOCOL_VERSION,
|
|
2396
|
+
HQ_RESUME_GAP_MAX_BYTES,
|
|
2397
|
+
HQ_RESUME_GAP_MAX_ENVELOPES,
|
|
2398
|
+
HQ_RESUME_GAP_MAX_STALE_MS,
|
|
2395
2399
|
HQ_TRANSCRIPT_TEXT_CAP,
|
|
2396
2400
|
parseHqEventPayload,
|
|
2397
2401
|
parseHqFrame,
|
|
@@ -2402,7 +2406,274 @@ import {
|
|
|
2402
2406
|
} from "@wrongstack/core/hq";
|
|
2403
2407
|
import { WebSocket as WebSocket2 } from "ws";
|
|
2404
2408
|
var MAX_EVENT_LOG = 5e3;
|
|
2405
|
-
function
|
|
2409
|
+
function computeIsLeader(clients, projectId, acceptedCapabilities) {
|
|
2410
|
+
if (!acceptedCapabilities.includes("control.receive")) return false;
|
|
2411
|
+
for (const other of clients.values()) {
|
|
2412
|
+
if (other.projectId === projectId && other.capabilities.includes("control.receive")) {
|
|
2413
|
+
return false;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
return true;
|
|
2417
|
+
}
|
|
2418
|
+
function promoteNewLeader(clients, projectId, excludeWs, excludeClient) {
|
|
2419
|
+
const survivors = [];
|
|
2420
|
+
for (const [otherWs, otherClient] of clients) {
|
|
2421
|
+
if (otherWs === excludeWs || otherClient === excludeClient) continue;
|
|
2422
|
+
if (otherClient.projectId !== projectId) continue;
|
|
2423
|
+
if (!otherClient.capabilities.includes("control.receive")) continue;
|
|
2424
|
+
survivors.push(otherClient);
|
|
2425
|
+
}
|
|
2426
|
+
if (survivors.length === 0) return null;
|
|
2427
|
+
survivors.sort((a, b) => Date.parse(b.connectedAt) - Date.parse(a.connectedAt));
|
|
2428
|
+
const promoted = survivors[0];
|
|
2429
|
+
if (promoted) {
|
|
2430
|
+
promoted.isLeader = true;
|
|
2431
|
+
return promoted.clientId;
|
|
2432
|
+
}
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
function detectLeaderLoss(lostClient, clients, browsers, reason, eventSink) {
|
|
2436
|
+
if (!lostClient.isLeader) return false;
|
|
2437
|
+
const detectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2438
|
+
const promotedLeaderId = promoteNewLeader(
|
|
2439
|
+
clients,
|
|
2440
|
+
lostClient.projectId,
|
|
2441
|
+
lostClient.ws,
|
|
2442
|
+
lostClient
|
|
2443
|
+
);
|
|
2444
|
+
const hasSurvivors = promotedLeaderId !== null;
|
|
2445
|
+
const machineId = lostClient.machineId?.trim() || lostClient.project.machineId.trim() || "unknown";
|
|
2446
|
+
const previousLeaderHandle = lostClient.clientId;
|
|
2447
|
+
const seq = nextPeerEventSeq(eventSink?.eventLog);
|
|
2448
|
+
let envelope;
|
|
2449
|
+
if (hasSurvivors) {
|
|
2450
|
+
if (checkPeerDedup(lostClient.projectId, previousLeaderHandle)) {
|
|
2451
|
+
return false;
|
|
2452
|
+
}
|
|
2453
|
+
const payload = {
|
|
2454
|
+
projectId: lostClient.projectId,
|
|
2455
|
+
machineId,
|
|
2456
|
+
leaderClientId: lostClient.clientId,
|
|
2457
|
+
previousLeaderHandle,
|
|
2458
|
+
reason,
|
|
2459
|
+
detectedAt
|
|
2460
|
+
};
|
|
2461
|
+
envelope = {
|
|
2462
|
+
id: `peer-${lostClient.clientId}-${Date.now()}`,
|
|
2463
|
+
type: "peer.rehydrate",
|
|
2464
|
+
schemaVersion: HQ_PROTOCOL_VERSION,
|
|
2465
|
+
timestamp: detectedAt,
|
|
2466
|
+
clientId: HQ_BROWSER_PEER_RESUME_CLIENT_ID,
|
|
2467
|
+
projectId: lostClient.projectId,
|
|
2468
|
+
seq,
|
|
2469
|
+
payload
|
|
2470
|
+
};
|
|
2471
|
+
recordPeerEmit(lostClient.projectId, previousLeaderHandle);
|
|
2472
|
+
} else {
|
|
2473
|
+
const payload = {
|
|
2474
|
+
projectId: lostClient.projectId,
|
|
2475
|
+
machineId,
|
|
2476
|
+
leaderClientId: lostClient.clientId,
|
|
2477
|
+
previousLeaderHandle,
|
|
2478
|
+
reason,
|
|
2479
|
+
detectedAt
|
|
2480
|
+
};
|
|
2481
|
+
envelope = {
|
|
2482
|
+
id: `peer-${lostClient.clientId}-${Date.now()}`,
|
|
2483
|
+
type: "peer.lost",
|
|
2484
|
+
schemaVersion: HQ_PROTOCOL_VERSION,
|
|
2485
|
+
timestamp: detectedAt,
|
|
2486
|
+
clientId: HQ_BROWSER_PEER_RESUME_CLIENT_ID,
|
|
2487
|
+
projectId: lostClient.projectId,
|
|
2488
|
+
seq,
|
|
2489
|
+
payload
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
if (eventSink !== void 0) {
|
|
2493
|
+
eventSink.eventLog.push(envelope);
|
|
2494
|
+
if (eventSink.eventLog.length > MAX_EVENT_LOG) {
|
|
2495
|
+
eventSink.eventLog.splice(0, eventSink.eventLog.length - MAX_EVENT_LOG);
|
|
2496
|
+
}
|
|
2497
|
+
eventSink.persistence?.eventLog.append(envelope);
|
|
2498
|
+
}
|
|
2499
|
+
broadcastEvent(envelope, browsers);
|
|
2500
|
+
for (const [peerWs, peerClient] of clients) {
|
|
2501
|
+
if (peerWs === lostClient.ws) continue;
|
|
2502
|
+
if (peerClient.projectId !== lostClient.projectId) continue;
|
|
2503
|
+
sendGuarded(peerWs, JSON.stringify({ type: "hq.event", event: envelope }));
|
|
2504
|
+
}
|
|
2505
|
+
return true;
|
|
2506
|
+
}
|
|
2507
|
+
var peerEventSeq = 0;
|
|
2508
|
+
function nextPeerEventSeq(eventLog) {
|
|
2509
|
+
if (eventLog !== void 0) {
|
|
2510
|
+
for (const env of eventLog) {
|
|
2511
|
+
if (env.clientId === HQ_BROWSER_PEER_RESUME_CLIENT_ID && env.seq > peerEventSeq) {
|
|
2512
|
+
peerEventSeq = env.seq;
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
peerEventSeq += 1;
|
|
2517
|
+
return peerEventSeq;
|
|
2518
|
+
}
|
|
2519
|
+
function fanoutKanbanDelta(message, clients, browsers, projectId) {
|
|
2520
|
+
let clientsNotified = 0;
|
|
2521
|
+
for (const peer of clients.values()) {
|
|
2522
|
+
if (peer.projectId === projectId) {
|
|
2523
|
+
sendGuarded(peer.ws, message);
|
|
2524
|
+
clientsNotified++;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
let browsersNotified = 0;
|
|
2528
|
+
for (const browserWs of browsers) {
|
|
2529
|
+
sendGuarded(browserWs, message);
|
|
2530
|
+
browsersNotified++;
|
|
2531
|
+
}
|
|
2532
|
+
return { clientsNotified, browsersNotified };
|
|
2533
|
+
}
|
|
2534
|
+
function handleClientResume(ws, clients, eventLog, frame, snapshotBroadcaster) {
|
|
2535
|
+
const client = clients.get(ws);
|
|
2536
|
+
if (!client) return;
|
|
2537
|
+
if (frame.clientId !== void 0 && frame.clientId !== client.clientId) {
|
|
2538
|
+
ws.close(1008, "resume clientId mismatch");
|
|
2539
|
+
return;
|
|
2540
|
+
}
|
|
2541
|
+
if (client.kind !== "browser" && frame.projectId !== void 0 && frame.projectId !== client.projectId) {
|
|
2542
|
+
ws.close(1008, "resume projectId mismatch");
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2545
|
+
client.lastSeenAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2546
|
+
const cursor = frame.lastSeqSeen;
|
|
2547
|
+
const now = Date.now();
|
|
2548
|
+
const recent = [];
|
|
2549
|
+
let cursorTimestamp;
|
|
2550
|
+
const skipPeerEnvelopes = client.clientId !== HQ_BROWSER_PEER_RESUME_CLIENT_ID;
|
|
2551
|
+
for (const env of eventLog) {
|
|
2552
|
+
if (env.clientId !== client.clientId) continue;
|
|
2553
|
+
if (skipPeerEnvelopes && (env.type === "peer.rehydrate" || env.type === "peer.lost")) {
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2556
|
+
if (env.seq === cursor) cursorTimestamp = env.timestamp;
|
|
2557
|
+
if (env.seq > cursor) {
|
|
2558
|
+
recent.push(env);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
if (cursor > 0 && cursorTimestamp === void 0) {
|
|
2562
|
+
if (snapshotBroadcaster !== void 0) {
|
|
2563
|
+
sendGuarded(ws, snapshotBroadcaster.currentSerialized());
|
|
2564
|
+
return;
|
|
2565
|
+
}
|
|
2566
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
2567
|
+
sendGuarded(
|
|
2568
|
+
ws,
|
|
2569
|
+
JSON.stringify({
|
|
2570
|
+
type: "hq.resume_reject",
|
|
2571
|
+
reason: "log_unavailable",
|
|
2572
|
+
detectedAt: nowIso
|
|
2573
|
+
})
|
|
2574
|
+
);
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2577
|
+
const hasStale = cursorTimestamp !== void 0 && now - Date.parse(cursorTimestamp) > HQ_RESUME_GAP_MAX_STALE_MS;
|
|
2578
|
+
if (hasStale) {
|
|
2579
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
2580
|
+
sendGuarded(
|
|
2581
|
+
ws,
|
|
2582
|
+
JSON.stringify({
|
|
2583
|
+
type: "hq.resume_reject",
|
|
2584
|
+
reason: "last_seen_too_old",
|
|
2585
|
+
detectedAt: nowIso
|
|
2586
|
+
})
|
|
2587
|
+
);
|
|
2588
|
+
return;
|
|
2589
|
+
}
|
|
2590
|
+
let serializedByteLength = 0;
|
|
2591
|
+
for (const env of recent) {
|
|
2592
|
+
serializedByteLength += Buffer.byteLength(JSON.stringify(env), "utf8");
|
|
2593
|
+
if (serializedByteLength > HQ_RESUME_GAP_MAX_BYTES) break;
|
|
2594
|
+
}
|
|
2595
|
+
const gapIsTooLarge = recent.length > HQ_RESUME_GAP_MAX_ENVELOPES || serializedByteLength > HQ_RESUME_GAP_MAX_BYTES;
|
|
2596
|
+
if (gapIsTooLarge) {
|
|
2597
|
+
if (snapshotBroadcaster !== void 0) {
|
|
2598
|
+
sendGuarded(ws, snapshotBroadcaster.currentSerialized());
|
|
2599
|
+
return;
|
|
2600
|
+
}
|
|
2601
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
2602
|
+
sendGuarded(
|
|
2603
|
+
ws,
|
|
2604
|
+
JSON.stringify({
|
|
2605
|
+
type: "hq.resume_reject",
|
|
2606
|
+
reason: "gap_too_large",
|
|
2607
|
+
detectedAt: nowIso
|
|
2608
|
+
})
|
|
2609
|
+
);
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
recent.sort((a, b) => a.seq - b.seq);
|
|
2613
|
+
sendGuarded(
|
|
2614
|
+
ws,
|
|
2615
|
+
JSON.stringify({
|
|
2616
|
+
type: "hq.resume_gap",
|
|
2617
|
+
lastSeqSeen: cursor,
|
|
2618
|
+
envelopes: recent,
|
|
2619
|
+
truncated: false
|
|
2620
|
+
})
|
|
2621
|
+
);
|
|
2622
|
+
return;
|
|
2623
|
+
}
|
|
2624
|
+
var PEER_DEDUP_WINDOW_MS = 60 * 60 * 1e3;
|
|
2625
|
+
var peerDedupMap = /* @__PURE__ */ new Map();
|
|
2626
|
+
function peerDedupKey(projectId, previousLeaderHandle) {
|
|
2627
|
+
return `${projectId}::${previousLeaderHandle}`;
|
|
2628
|
+
}
|
|
2629
|
+
function checkPeerDedup(projectId, previousLeaderHandle) {
|
|
2630
|
+
const key = peerDedupKey(projectId, previousLeaderHandle);
|
|
2631
|
+
const now = Date.now();
|
|
2632
|
+
for (const [k, ts] of peerDedupMap) {
|
|
2633
|
+
if (now - ts > PEER_DEDUP_WINDOW_MS) peerDedupMap.delete(k);
|
|
2634
|
+
}
|
|
2635
|
+
const last = peerDedupMap.get(key);
|
|
2636
|
+
return last !== void 0 && now - last <= PEER_DEDUP_WINDOW_MS;
|
|
2637
|
+
}
|
|
2638
|
+
function recordPeerEmit(projectId, previousLeaderHandle) {
|
|
2639
|
+
peerDedupMap.set(peerDedupKey(projectId, previousLeaderHandle), Date.now());
|
|
2640
|
+
}
|
|
2641
|
+
function browserResumeClient(ws, clientId) {
|
|
2642
|
+
return /* @__PURE__ */ new Map([
|
|
2643
|
+
[
|
|
2644
|
+
ws,
|
|
2645
|
+
{
|
|
2646
|
+
ws,
|
|
2647
|
+
clientId,
|
|
2648
|
+
projectId: "",
|
|
2649
|
+
project: {
|
|
2650
|
+
projectId: "",
|
|
2651
|
+
projectName: "",
|
|
2652
|
+
projectRoot: "",
|
|
2653
|
+
machineId: "",
|
|
2654
|
+
workspaceKind: "git"
|
|
2655
|
+
},
|
|
2656
|
+
kind: "browser",
|
|
2657
|
+
connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2658
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2659
|
+
capabilities: [],
|
|
2660
|
+
declaredRedactionPolicy: {
|
|
2661
|
+
rawContent: false,
|
|
2662
|
+
toolArgs: "summary",
|
|
2663
|
+
paths: "project-relative"
|
|
2664
|
+
},
|
|
2665
|
+
lastEventSeq: 0,
|
|
2666
|
+
mailboxes: /* @__PURE__ */ new Map(),
|
|
2667
|
+
sessions: /* @__PURE__ */ new Map(),
|
|
2668
|
+
fleets: /* @__PURE__ */ new Map(),
|
|
2669
|
+
mcpSnapshots: /* @__PURE__ */ new Map(),
|
|
2670
|
+
commandQueue: [],
|
|
2671
|
+
isLeader: false
|
|
2672
|
+
}
|
|
2673
|
+
]
|
|
2674
|
+
]);
|
|
2675
|
+
}
|
|
2676
|
+
function handleBrowser(ws, snapshotBroadcaster, browsers, eventLog) {
|
|
2406
2677
|
browsers.add(ws);
|
|
2407
2678
|
ws.on("error", (err) => {
|
|
2408
2679
|
console.warn(
|
|
@@ -2415,6 +2686,40 @@ function handleBrowser(ws, snapshotBroadcaster, browsers) {
|
|
|
2415
2686
|
);
|
|
2416
2687
|
});
|
|
2417
2688
|
sendGuarded(ws, snapshotBroadcaster.currentSerialized());
|
|
2689
|
+
ws.on("message", (data) => {
|
|
2690
|
+
let raw;
|
|
2691
|
+
if (typeof data === "string") {
|
|
2692
|
+
raw = Buffer.from(data, "utf8");
|
|
2693
|
+
} else if (Buffer.isBuffer(data)) {
|
|
2694
|
+
raw = data;
|
|
2695
|
+
} else if (Array.isArray(data)) {
|
|
2696
|
+
raw = Buffer.concat(data);
|
|
2697
|
+
} else {
|
|
2698
|
+
raw = Buffer.from(new TextDecoder().decode(data), "utf8");
|
|
2699
|
+
}
|
|
2700
|
+
const parsed = parseHqFrame(raw);
|
|
2701
|
+
if (!parsed.ok) {
|
|
2702
|
+
const code = parsed.reason === "invalid-json" ? 1003 : 1008;
|
|
2703
|
+
ws.close(code, `invalid frame: ${parsed.reason}`);
|
|
2704
|
+
return;
|
|
2705
|
+
}
|
|
2706
|
+
const frame = parsed.frame;
|
|
2707
|
+
if (frame.type !== "client.resume") {
|
|
2708
|
+
ws.close(1008, "browser frame must be client.resume");
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
if (frame.clientId === void 0 || frame.clientId.length === 0) {
|
|
2712
|
+
ws.close(1008, "browser resume requires clientId");
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
handleClientResume(
|
|
2716
|
+
ws,
|
|
2717
|
+
browserResumeClient(ws, frame.clientId),
|
|
2718
|
+
eventLog,
|
|
2719
|
+
frame,
|
|
2720
|
+
snapshotBroadcaster
|
|
2721
|
+
);
|
|
2722
|
+
});
|
|
2418
2723
|
ws.on("close", () => {
|
|
2419
2724
|
browsers.delete(ws);
|
|
2420
2725
|
});
|
|
@@ -2463,9 +2768,16 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
2463
2768
|
(capability) => capability === "control.receive" || canPublishTelemetry
|
|
2464
2769
|
);
|
|
2465
2770
|
const declaredRedactionPolicy = resolveHqRedactionPolicy(payload.redactionPolicy);
|
|
2771
|
+
const supersededLeaders = [];
|
|
2772
|
+
let inheritedLeader = false;
|
|
2466
2773
|
for (const [otherWs, otherClient] of clients) {
|
|
2774
|
+
const sameClientId = otherClient.clientId === payload.client.clientId;
|
|
2467
2775
|
const samePublisher = otherClient.projectId === payload.project.projectId && otherClient.kind === payload.client.kind && otherClient.pid !== void 0 && payload.client.pid !== void 0 && otherClient.pid === payload.client.pid && (otherClient.machineId || otherClient.project.machineId) === (payload.client.machineId || payload.project.machineId);
|
|
2468
|
-
if (otherWs !== ws && (
|
|
2776
|
+
if (otherWs !== ws && (sameClientId || samePublisher && otherClient.sessions.size === 0)) {
|
|
2777
|
+
if (otherClient.isLeader) {
|
|
2778
|
+
if (sameClientId) inheritedLeader = true;
|
|
2779
|
+
else supersededLeaders.push(otherClient);
|
|
2780
|
+
}
|
|
2469
2781
|
clients.delete(otherWs);
|
|
2470
2782
|
otherWs.close(4001, "superseded by a newer HQ connection");
|
|
2471
2783
|
}
|
|
@@ -2490,10 +2802,19 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
2490
2802
|
sessions: /* @__PURE__ */ new Map(),
|
|
2491
2803
|
fleets: /* @__PURE__ */ new Map(),
|
|
2492
2804
|
mcpSnapshots: /* @__PURE__ */ new Map(),
|
|
2493
|
-
commandQueue: []
|
|
2805
|
+
commandQueue: [],
|
|
2806
|
+
// Leader for the project is the unique client with `control.receive`
|
|
2807
|
+
// capability. First such client wins; subsequent clients with the
|
|
2808
|
+
// capability are followers. Same-clientId reconnects inherit this
|
|
2809
|
+
// flag from the superseded socket because that identity never really
|
|
2810
|
+
// disappeared; different-client supersedes still use the loss detector.
|
|
2811
|
+
isLeader: inheritedLeader || computeIsLeader(clients, payload.project.projectId, acceptedCapabilities)
|
|
2494
2812
|
};
|
|
2495
2813
|
clients.set(ws, client);
|
|
2496
2814
|
registered = true;
|
|
2815
|
+
for (const lostLeader of supersededLeaders) {
|
|
2816
|
+
detectLeaderLoss(lostLeader, clients, browsers, "crash", { eventLog, persistence });
|
|
2817
|
+
}
|
|
2497
2818
|
const welcome = {
|
|
2498
2819
|
type: "hq.welcome",
|
|
2499
2820
|
protocolVersion: HQ_PROTOCOL_VERSION,
|
|
@@ -2583,6 +2904,10 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
2583
2904
|
}
|
|
2584
2905
|
return;
|
|
2585
2906
|
}
|
|
2907
|
+
if (frame.type === "client.resume") {
|
|
2908
|
+
handleClientResume(ws, clients, eventLog, frame, snapshotBroadcaster);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2586
2911
|
if (frame.type === "client.event") {
|
|
2587
2912
|
const client = clients.get(ws);
|
|
2588
2913
|
if (!client) return;
|
|
@@ -2636,9 +2961,7 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
2636
2961
|
tombstones: merged.tombstones.filter((record) => touched.has(record.boardId))
|
|
2637
2962
|
};
|
|
2638
2963
|
const message = JSON.stringify({ type: "hq.kanban_snapshot", payload: delta });
|
|
2639
|
-
|
|
2640
|
-
if (peer.projectId === client.projectId) sendGuarded(peer.ws, message);
|
|
2641
|
-
}
|
|
2964
|
+
fanoutKanbanDelta(message, clients, browsers, client.projectId);
|
|
2642
2965
|
}).catch((error) => {
|
|
2643
2966
|
console.warn(
|
|
2644
2967
|
JSON.stringify({
|
|
@@ -2768,7 +3091,11 @@ function handleClient(ws, clients, browsers, eventLog, auth, snapshotBroadcaster
|
|
|
2768
3091
|
}
|
|
2769
3092
|
});
|
|
2770
3093
|
ws.on("close", () => {
|
|
3094
|
+
const lostClient = clients.get(ws);
|
|
2771
3095
|
clients.delete(ws);
|
|
3096
|
+
if (lostClient) {
|
|
3097
|
+
detectLeaderLoss(lostClient, clients, browsers, "graceful", { eventLog, persistence });
|
|
3098
|
+
}
|
|
2772
3099
|
snapshotBroadcaster.broadcast();
|
|
2773
3100
|
});
|
|
2774
3101
|
}
|
|
@@ -2837,6 +3164,9 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
2837
3164
|
const transcripts = /* @__PURE__ */ new Map();
|
|
2838
3165
|
const agentMessages = /* @__PURE__ */ new Map();
|
|
2839
3166
|
const mailboxGateways = /* @__PURE__ */ new Map();
|
|
3167
|
+
const MAILBOX_GATEWAY_IDLE_TTL_MS = 15 * 6e4;
|
|
3168
|
+
const MAILBOX_GATEWAY_SWEEP_INTERVAL_MS = 6e4;
|
|
3169
|
+
const mailboxGatewayLastUsed = /* @__PURE__ */ new Map();
|
|
2840
3170
|
const mailboxGatewayRateLimiter = new MailboxHttpRateLimiter();
|
|
2841
3171
|
const mailboxGatewayRateLimitCleanup = setInterval(
|
|
2842
3172
|
() => mailboxGatewayRateLimiter.cleanup(),
|
|
@@ -2924,7 +3254,10 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
2924
3254
|
};
|
|
2925
3255
|
const getMailboxGateway = (projectDir) => {
|
|
2926
3256
|
const existing = mailboxGateways.get(projectDir);
|
|
2927
|
-
if (existing)
|
|
3257
|
+
if (existing) {
|
|
3258
|
+
mailboxGatewayLastUsed.set(projectDir, Date.now());
|
|
3259
|
+
return existing;
|
|
3260
|
+
}
|
|
2928
3261
|
const eventEmitter = new MailboxEventEmitter();
|
|
2929
3262
|
const mailbox = createProjectMailbox({ projectDir, eventEmitter });
|
|
2930
3263
|
const router = createMailboxHttpRouter({
|
|
@@ -2941,8 +3274,25 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
2941
3274
|
});
|
|
2942
3275
|
const gateway = { mailbox, router };
|
|
2943
3276
|
mailboxGateways.set(projectDir, gateway);
|
|
3277
|
+
mailboxGatewayLastUsed.set(projectDir, Date.now());
|
|
2944
3278
|
return gateway;
|
|
2945
3279
|
};
|
|
3280
|
+
const evictIdleMailboxGateways = () => {
|
|
3281
|
+
const cutoff = Date.now() - MAILBOX_GATEWAY_IDLE_TTL_MS;
|
|
3282
|
+
for (const [projectDir, gateway] of [...mailboxGateways]) {
|
|
3283
|
+
if ((mailboxGatewayLastUsed.get(projectDir) ?? 0) > cutoff) continue;
|
|
3284
|
+
if (gateway.router.hasActiveStreams()) continue;
|
|
3285
|
+
mailboxGateways.delete(projectDir);
|
|
3286
|
+
mailboxGatewayLastUsed.delete(projectDir);
|
|
3287
|
+
gateway.router.close();
|
|
3288
|
+
void gateway.mailbox.close().catch(() => void 0);
|
|
3289
|
+
}
|
|
3290
|
+
};
|
|
3291
|
+
const mailboxGatewaySweepTimer = setInterval(
|
|
3292
|
+
evictIdleMailboxGateways,
|
|
3293
|
+
MAILBOX_GATEWAY_SWEEP_INTERVAL_MS
|
|
3294
|
+
);
|
|
3295
|
+
mailboxGatewaySweepTimer.unref?.();
|
|
2946
3296
|
const alertEngine = new HqAlertEngine({
|
|
2947
3297
|
onAlert: (alert) => {
|
|
2948
3298
|
const msg = toAlertMessage(alert);
|
|
@@ -2989,8 +3339,13 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
2989
3339
|
let changed = false;
|
|
2990
3340
|
for (const [ws, client] of clients.entries()) {
|
|
2991
3341
|
if (new Date(client.lastSeenAt).getTime() < cutoff) {
|
|
3342
|
+
const lostClient = client;
|
|
2992
3343
|
ws.terminate();
|
|
2993
3344
|
clients.delete(ws);
|
|
3345
|
+
detectLeaderLoss(lostClient, clients, browsers, "heartbeat-timeout", {
|
|
3346
|
+
eventLog,
|
|
3347
|
+
persistence
|
|
3348
|
+
});
|
|
2994
3349
|
changed = true;
|
|
2995
3350
|
continue;
|
|
2996
3351
|
}
|
|
@@ -3010,8 +3365,13 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
3010
3365
|
}
|
|
3011
3366
|
}
|
|
3012
3367
|
if (client.capabilities.includes("session.summary") && client.sessions.size === 0 && Date.now() - Date.parse(client.connectedAt) > sessionSnapshotTtlMs) {
|
|
3368
|
+
const lostClient = client;
|
|
3013
3369
|
ws.terminate();
|
|
3014
3370
|
clients.delete(ws);
|
|
3371
|
+
detectLeaderLoss(lostClient, clients, browsers, "heartbeat-timeout", {
|
|
3372
|
+
eventLog,
|
|
3373
|
+
persistence
|
|
3374
|
+
});
|
|
3015
3375
|
changed = true;
|
|
3016
3376
|
}
|
|
3017
3377
|
}
|
|
@@ -3119,7 +3479,7 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
3119
3479
|
});
|
|
3120
3480
|
wss.on("connection", (ws, req, pathname) => {
|
|
3121
3481
|
if (pathname === "/ws/browser") {
|
|
3122
|
-
handleBrowser(ws, snapshotBroadcaster, browsers);
|
|
3482
|
+
handleBrowser(ws, snapshotBroadcaster, browsers, eventLog);
|
|
3123
3483
|
} else {
|
|
3124
3484
|
const token = new URL(req.url ?? "/", `http://${host}:${port}`).searchParams.get("token");
|
|
3125
3485
|
handleClient(
|
|
@@ -3246,6 +3606,7 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
3246
3606
|
clearInterval(browserHeartbeatTimer);
|
|
3247
3607
|
clearInterval(timeseriesFlushTimer);
|
|
3248
3608
|
clearInterval(mailboxGatewayRateLimitCleanup);
|
|
3609
|
+
clearInterval(mailboxGatewaySweepTimer);
|
|
3249
3610
|
clearInterval(sessionCleanupTimer);
|
|
3250
3611
|
stopAlertEngine();
|
|
3251
3612
|
authWatcher.close();
|
|
@@ -3261,6 +3622,7 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
|
|
|
3261
3622
|
({ mailbox }) => mailbox.close().catch(() => void 0)
|
|
3262
3623
|
);
|
|
3263
3624
|
mailboxGateways.clear();
|
|
3625
|
+
mailboxGatewayLastUsed.clear();
|
|
3264
3626
|
void Promise.all([
|
|
3265
3627
|
...mailboxCloses,
|
|
3266
3628
|
persistence.eventLog.drain(),
|
|
@@ -3300,4 +3662,4 @@ export {
|
|
|
3300
3662
|
startHqServer,
|
|
3301
3663
|
HqInsecureExposureError2 as HqInsecureExposureError
|
|
3302
3664
|
};
|
|
3303
|
-
//# sourceMappingURL=chunk-
|
|
3665
|
+
//# sourceMappingURL=chunk-7JABKXET.js.map
|