obsidian-integration-testing 9.2.1 → 9.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Ties a harness-owned Obsidian instance's lifetime to the harness process that
5
+ * launched it, in the one direction the operating system will not do for us.
6
+ *
7
+ * The owned instance is already a child of the harness process, but that link
8
+ * carries no lifetime guarantee. Windows never propagates a parent's death to
9
+ * its children — an orphan simply keeps running with a stale parent id — and on
10
+ * POSIX a `SIGKILL` aimed at a single pid never cascades either. The instance is
11
+ * additionally spawned `detached`, so it is not even in the harness's process
12
+ * group. Teardown therefore relies entirely on the harness running its own
13
+ * cleanup (`killProcessTree` from an `exit`/signal handler), which is exactly
14
+ * what a `SIGKILL`, a Task Manager kill, or an IDE stop button denies it. Every
15
+ * such kill leaks a hidden Obsidian holding a user-data dir and a CDP port, and
16
+ * they accumulate: the next run picks a fresh temp dir and a free port, so
17
+ * nothing collides and nothing complains.
18
+ *
19
+ * The guaranteed fix is an OS primitive — a Windows Job Object with
20
+ * `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`, or `prctl(PR_SET_PDEATHSIG)` on Linux —
21
+ * but neither is reachable from Node without a native addon, which is far too
22
+ * heavy a dependency for this harness.
23
+ *
24
+ * So we use the one cross-platform resource the kernel *does* reclaim
25
+ * deterministically on process death: a socket. The harness listens on a
26
+ * loopback port and the instance's renderer connects to it. However the harness
27
+ * dies — cleanly, `SIGKILL`ed, or crashed — the kernel closes its end, the
28
+ * renderer sees `close`, and the window destroys itself. No polling, no
29
+ * heartbeat interval, no timeout to tune.
30
+ *
31
+ * Deliberately fail-open: the renderer only arms the destroy handler after the
32
+ * connection is actually established. A watchdog that cannot reach the harness
33
+ * leaves the instance running rather than killing a window the developer is
34
+ * working in.
35
+ */
36
+ /**
37
+ * A listening loopback server whose accepted connections act as liveness tokens
38
+ * for the harness process.
39
+ */
40
+ export interface ParentLivenessServer {
41
+ /** Stops listening and drops every accepted connection. */
42
+ close(): void;
43
+ /** The loopback port the renderer watchdog should connect back to. */
44
+ readonly port: number;
45
+ }
46
+ /**
47
+ * Loopback host the liveness server binds to. Never exposed off-machine.
48
+ */
49
+ export declare const PARENT_LIVENESS_HOST = "127.0.0.1";
50
+ /**
51
+ * Builds the expression evaluated in the owned instance's renderer to arm the
52
+ * watchdog.
53
+ *
54
+ * Written in ES5 style (`var`, `function`) with no optional chaining, matching
55
+ * {@link DISMISS_TRUST_DIALOG_EXPR}: the same expression has to parse on the
56
+ * Chromium 80-era renderers of the oldest supported Obsidian versions (L26).
57
+ *
58
+ * Arming is idempotent — a second evaluation finds the stored socket and
59
+ * returns without opening another connection, so a retried readiness pass does
60
+ * not pile up sockets.
61
+ *
62
+ * @param port - The loopback port returned by {@link startParentLivenessServer}.
63
+ * @returns The expression to evaluate, yielding `'armed'`, `'already-armed'`, or `'unavailable'`.
64
+ */
65
+ export declare function buildParentLivenessWatchdogExpr(port: number): string;
66
+ /**
67
+ * Starts the loopback liveness server the owned instance's renderer connects
68
+ * back to.
69
+ *
70
+ * The server and every accepted socket are `unref`ed, so holding a watchdog
71
+ * connection open never keeps the harness process alive on its own — the
72
+ * connection is a token the kernel reclaims, not work to wait on.
73
+ *
74
+ * @returns A {@link Promise} resolving to the listening {@link ParentLivenessServer}.
75
+ */
76
+ export declare function startParentLivenessServer(): Promise<ParentLivenessServer>;
@@ -0,0 +1,67 @@
1
+ import { createServer } from "node:net";
2
+ const PARENT_LIVENESS_HOST = "127.0.0.1";
3
+ function buildParentLivenessWatchdogExpr(port) {
4
+ return `(function() {
5
+ var FLAG = '__obsidianIntegrationTestingParentLiveness';
6
+ if (window[FLAG]) { return 'already-armed'; }
7
+ var net;
8
+ try {
9
+ net = window.require('node:net');
10
+ } catch (nodePrefixError) {
11
+ try {
12
+ net = window.require('net');
13
+ } catch (barePrefixError) {
14
+ return 'unavailable';
15
+ }
16
+ }
17
+ var socket = net.connect(${String(port)}, '${PARENT_LIVENESS_HOST}');
18
+ window[FLAG] = socket;
19
+ var isConnected = false;
20
+ socket.on('connect', function() { isConnected = true; });
21
+ socket.on('error', function() { /* Handled by the close listener below. */ });
22
+ socket.on('close', function() {
23
+ if (!isConnected) { return; }
24
+ try {
25
+ window.electronWindow.destroy();
26
+ } catch (destroyError) {
27
+ window.close();
28
+ }
29
+ });
30
+ return 'armed';
31
+ })()`;
32
+ }
33
+ async function startParentLivenessServer() {
34
+ const server = createServer((socket) => {
35
+ socket.unref();
36
+ socket.on("error", () => {
37
+ });
38
+ });
39
+ server.unref();
40
+ const port = await listenOnFreeLoopbackPort(server);
41
+ return {
42
+ close() {
43
+ server.close();
44
+ },
45
+ port
46
+ };
47
+ }
48
+ async function listenOnFreeLoopbackPort(server) {
49
+ return new Promise((resolve, reject) => {
50
+ server.once("error", reject);
51
+ server.listen(0, PARENT_LIVENESS_HOST, () => {
52
+ const address = server.address();
53
+ if (address === null || typeof address === "string") {
54
+ server.close();
55
+ reject(new Error("Failed to determine the parent-liveness port."));
56
+ return;
57
+ }
58
+ resolve(address.port);
59
+ });
60
+ });
61
+ }
62
+ export {
63
+ PARENT_LIVENESS_HOST,
64
+ buildParentLivenessWatchdogExpr,
65
+ startParentLivenessServer
66
+ };
67
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3BhcmVudC1saXZlbmVzcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRpZXMgYSBoYXJuZXNzLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlJ3MgbGlmZXRpbWUgdG8gdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0XG4gKiBsYXVuY2hlZCBpdCwgaW4gdGhlIG9uZSBkaXJlY3Rpb24gdGhlIG9wZXJhdGluZyBzeXN0ZW0gd2lsbCBub3QgZG8gZm9yIHVzLlxuICpcbiAqIFRoZSBvd25lZCBpbnN0YW5jZSBpcyBhbHJlYWR5IGEgY2hpbGQgb2YgdGhlIGhhcm5lc3MgcHJvY2VzcywgYnV0IHRoYXQgbGlua1xuICogY2FycmllcyBubyBsaWZldGltZSBndWFyYW50ZWUuIFdpbmRvd3MgbmV2ZXIgcHJvcGFnYXRlcyBhIHBhcmVudCdzIGRlYXRoIHRvXG4gKiBpdHMgY2hpbGRyZW4gXHUyMDE0IGFuIG9ycGhhbiBzaW1wbHkga2VlcHMgcnVubmluZyB3aXRoIGEgc3RhbGUgcGFyZW50IGlkIFx1MjAxNCBhbmQgb25cbiAqIFBPU0lYIGEgYFNJR0tJTExgIGFpbWVkIGF0IGEgc2luZ2xlIHBpZCBuZXZlciBjYXNjYWRlcyBlaXRoZXIuIFRoZSBpbnN0YW5jZSBpc1xuICogYWRkaXRpb25hbGx5IHNwYXduZWQgYGRldGFjaGVkYCwgc28gaXQgaXMgbm90IGV2ZW4gaW4gdGhlIGhhcm5lc3MncyBwcm9jZXNzXG4gKiBncm91cC4gVGVhcmRvd24gdGhlcmVmb3JlIHJlbGllcyBlbnRpcmVseSBvbiB0aGUgaGFybmVzcyBydW5uaW5nIGl0cyBvd25cbiAqIGNsZWFudXAgKGBraWxsUHJvY2Vzc1RyZWVgIGZyb20gYW4gYGV4aXRgL3NpZ25hbCBoYW5kbGVyKSwgd2hpY2ggaXMgZXhhY3RseVxuICogd2hhdCBhIGBTSUdLSUxMYCwgYSBUYXNrIE1hbmFnZXIga2lsbCwgb3IgYW4gSURFIHN0b3AgYnV0dG9uIGRlbmllcyBpdC4gRXZlcnlcbiAqIHN1Y2gga2lsbCBsZWFrcyBhIGhpZGRlbiBPYnNpZGlhbiBob2xkaW5nIGEgdXNlci1kYXRhIGRpciBhbmQgYSBDRFAgcG9ydCwgYW5kXG4gKiB0aGV5IGFjY3VtdWxhdGU6IHRoZSBuZXh0IHJ1biBwaWNrcyBhIGZyZXNoIHRlbXAgZGlyIGFuZCBhIGZyZWUgcG9ydCwgc29cbiAqIG5vdGhpbmcgY29sbGlkZXMgYW5kIG5vdGhpbmcgY29tcGxhaW5zLlxuICpcbiAqIFRoZSBndWFyYW50ZWVkIGZpeCBpcyBhbiBPUyBwcmltaXRpdmUgXHUyMDE0IGEgV2luZG93cyBKb2IgT2JqZWN0IHdpdGhcbiAqIGBKT0JfT0JKRUNUX0xJTUlUX0tJTExfT05fSk9CX0NMT1NFYCwgb3IgYHByY3RsKFBSX1NFVF9QREVBVEhTSUcpYCBvbiBMaW51eCBcdTIwMTRcbiAqIGJ1dCBuZWl0aGVyIGlzIHJlYWNoYWJsZSBmcm9tIE5vZGUgd2l0aG91dCBhIG5hdGl2ZSBhZGRvbiwgd2hpY2ggaXMgZmFyIHRvb1xuICogaGVhdnkgYSBkZXBlbmRlbmN5IGZvciB0aGlzIGhhcm5lc3MuXG4gKlxuICogU28gd2UgdXNlIHRoZSBvbmUgY3Jvc3MtcGxhdGZvcm0gcmVzb3VyY2UgdGhlIGtlcm5lbCAqZG9lcyogcmVjbGFpbVxuICogZGV0ZXJtaW5pc3RpY2FsbHkgb24gcHJvY2VzcyBkZWF0aDogYSBzb2NrZXQuIFRoZSBoYXJuZXNzIGxpc3RlbnMgb24gYVxuICogbG9vcGJhY2sgcG9ydCBhbmQgdGhlIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHMgdG8gaXQuIEhvd2V2ZXIgdGhlIGhhcm5lc3NcbiAqIGRpZXMgXHUyMDE0IGNsZWFubHksIGBTSUdLSUxMYGVkLCBvciBjcmFzaGVkIFx1MjAxNCB0aGUga2VybmVsIGNsb3NlcyBpdHMgZW5kLCB0aGVcbiAqIHJlbmRlcmVyIHNlZXMgYGNsb3NlYCwgYW5kIHRoZSB3aW5kb3cgZGVzdHJveXMgaXRzZWxmLiBObyBwb2xsaW5nLCBub1xuICogaGVhcnRiZWF0IGludGVydmFsLCBubyB0aW1lb3V0IHRvIHR1bmUuXG4gKlxuICogRGVsaWJlcmF0ZWx5IGZhaWwtb3BlbjogdGhlIHJlbmRlcmVyIG9ubHkgYXJtcyB0aGUgZGVzdHJveSBoYW5kbGVyIGFmdGVyIHRoZVxuICogY29ubmVjdGlvbiBpcyBhY3R1YWxseSBlc3RhYmxpc2hlZC4gQSB3YXRjaGRvZyB0aGF0IGNhbm5vdCByZWFjaCB0aGUgaGFybmVzc1xuICogbGVhdmVzIHRoZSBpbnN0YW5jZSBydW5uaW5nIHJhdGhlciB0aGFuIGtpbGxpbmcgYSB3aW5kb3cgdGhlIGRldmVsb3BlciBpc1xuICogd29ya2luZyBpbi5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ25vZGU6bmV0JztcblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSAnbm9kZTpuZXQnO1xuXG4vKipcbiAqIEEgbGlzdGVuaW5nIGxvb3BiYWNrIHNlcnZlciB3aG9zZSBhY2NlcHRlZCBjb25uZWN0aW9ucyBhY3QgYXMgbGl2ZW5lc3MgdG9rZW5zXG4gKiBmb3IgdGhlIGhhcm5lc3MgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJlbnRMaXZlbmVzc1NlcnZlciB7XG4gIC8qKiBTdG9wcyBsaXN0ZW5pbmcgYW5kIGRyb3BzIGV2ZXJ5IGFjY2VwdGVkIGNvbm5lY3Rpb24uICovXG4gIGNsb3NlKCk6IHZvaWQ7XG5cbiAgLyoqIFRoZSBsb29wYmFjayBwb3J0IHRoZSByZW5kZXJlciB3YXRjaGRvZyBzaG91bGQgY29ubmVjdCBiYWNrIHRvLiAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG59XG5cbi8qKlxuICogTG9vcGJhY2sgaG9zdCB0aGUgbGl2ZW5lc3Mgc2VydmVyIGJpbmRzIHRvLiBOZXZlciBleHBvc2VkIG9mZi1tYWNoaW5lLlxuICovXG5leHBvcnQgY29uc3QgUEFSRU5UX0xJVkVORVNTX0hPU1QgPSAnMTI3LjAuMC4xJztcblxuLyoqXG4gKiBCdWlsZHMgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVkIGluIHRoZSBvd25lZCBpbnN0YW5jZSdzIHJlbmRlcmVyIHRvIGFybSB0aGVcbiAqIHdhdGNoZG9nLlxuICpcbiAqIFdyaXR0ZW4gaW4gRVM1IHN0eWxlIChgdmFyYCwgYGZ1bmN0aW9uYCkgd2l0aCBubyBvcHRpb25hbCBjaGFpbmluZywgbWF0Y2hpbmdcbiAqIHtAbGluayBESVNNSVNTX1RSVVNUX0RJQUxPR19FWFBSfTogdGhlIHNhbWUgZXhwcmVzc2lvbiBoYXMgdG8gcGFyc2Ugb24gdGhlXG4gKiBDaHJvbWl1bSA4MC1lcmEgcmVuZGVyZXJzIG9mIHRoZSBvbGRlc3Qgc3VwcG9ydGVkIE9ic2lkaWFuIHZlcnNpb25zIChMMjYpLlxuICpcbiAqIEFybWluZyBpcyBpZGVtcG90ZW50IFx1MjAxNCBhIHNlY29uZCBldmFsdWF0aW9uIGZpbmRzIHRoZSBzdG9yZWQgc29ja2V0IGFuZFxuICogcmV0dXJucyB3aXRob3V0IG9wZW5pbmcgYW5vdGhlciBjb25uZWN0aW9uLCBzbyBhIHJldHJpZWQgcmVhZGluZXNzIHBhc3MgZG9lc1xuICogbm90IHBpbGUgdXAgc29ja2V0cy5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBsb29wYmFjayBwb3J0IHJldHVybmVkIGJ5IHtAbGluayBzdGFydFBhcmVudExpdmVuZXNzU2VydmVyfS5cbiAqIEByZXR1cm5zIFRoZSBleHByZXNzaW9uIHRvIGV2YWx1YXRlLCB5aWVsZGluZyBgJ2FybWVkJ2AsIGAnYWxyZWFkeS1hcm1lZCdgLCBvciBgJ3VuYXZhaWxhYmxlJ2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBhcmVudExpdmVuZXNzV2F0Y2hkb2dFeHByKHBvcnQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgKGZ1bmN0aW9uKCkge1xuICB2YXIgRkxBRyA9ICdfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nUGFyZW50TGl2ZW5lc3MnO1xuICBpZiAod2luZG93W0ZMQUddKSB7IHJldHVybiAnYWxyZWFkeS1hcm1lZCc7IH1cbiAgdmFyIG5ldDtcbiAgdHJ5IHtcbiAgICBuZXQgPSB3aW5kb3cucmVxdWlyZSgnbm9kZTpuZXQnKTtcbiAgfSBjYXRjaCAobm9kZVByZWZpeEVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIG5ldCA9IHdpbmRvdy5yZXF1aXJlKCduZXQnKTtcbiAgICB9IGNhdGNoIChiYXJlUHJlZml4RXJyb3IpIHtcbiAgICAgIHJldHVybiAndW5hdmFpbGFibGUnO1xuICAgIH1cbiAgfVxuICB2YXIgc29ja2V0ID0gbmV0LmNvbm5lY3QoJHtTdHJpbmcocG9ydCl9LCAnJHtQQVJFTlRfTElWRU5FU1NfSE9TVH0nKTtcbiAgd2luZG93W0ZMQUddID0gc29ja2V0O1xuICB2YXIgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24oKSB7IGlzQ29ubmVjdGVkID0gdHJ1ZTsgfSk7XG4gIHNvY2tldC5vbignZXJyb3InLCBmdW5jdGlvbigpIHsgLyogSGFuZGxlZCBieSB0aGUgY2xvc2UgbGlzdGVuZXIgYmVsb3cuICovIH0pO1xuICBzb2NrZXQub24oJ2Nsb3NlJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFpc0Nvbm5lY3RlZCkgeyByZXR1cm47IH1cbiAgICB0cnkge1xuICAgICAgd2luZG93LmVsZWN0cm9uV2luZG93LmRlc3Ryb3koKTtcbiAgICB9IGNhdGNoIChkZXN0cm95RXJyb3IpIHtcbiAgICAgIHdpbmRvdy5jbG9zZSgpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiAnYXJtZWQnO1xufSkoKWA7XG59XG5cbi8qKlxuICogU3RhcnRzIHRoZSBsb29wYmFjayBsaXZlbmVzcyBzZXJ2ZXIgdGhlIG93bmVkIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHNcbiAqIGJhY2sgdG8uXG4gKlxuICogVGhlIHNlcnZlciBhbmQgZXZlcnkgYWNjZXB0ZWQgc29ja2V0IGFyZSBgdW5yZWZgZWQsIHNvIGhvbGRpbmcgYSB3YXRjaGRvZ1xuICogY29ubmVjdGlvbiBvcGVuIG5ldmVyIGtlZXBzIHRoZSBoYXJuZXNzIHByb2Nlc3MgYWxpdmUgb24gaXRzIG93biBcdTIwMTQgdGhlXG4gKiBjb25uZWN0aW9uIGlzIGEgdG9rZW4gdGhlIGtlcm5lbCByZWNsYWltcywgbm90IHdvcmsgdG8gd2FpdCBvbi5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIGxpc3RlbmluZyB7QGxpbmsgUGFyZW50TGl2ZW5lc3NTZXJ2ZXJ9LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQYXJlbnRMaXZlbmVzc1NlcnZlcigpOiBQcm9taXNlPFBhcmVudExpdmVuZXNzU2VydmVyPiB7XG4gIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigoc29ja2V0KSA9PiB7XG4gICAgc29ja2V0LnVucmVmKCk7XG4gICAgLy8gVGhlIGNvbm5lY3Rpb24gY2FycmllcyBubyBkYXRhIFx1MjAxNCBpdCBleGlzdHMgb25seSBzbyBpdHMgY2xvc2UgaXMgb2JzZXJ2YWJsZS5cbiAgICBzb2NrZXQub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgLy8gQSByZW5kZXJlciB0b3JuIGRvd24gbWlkLWNvbm5lY3Rpb24gcmVzZXRzIHJhdGhlciB0aGFuIGNsb3Nlczsgbm90IGFuIGVycm9yIGhlcmUuXG4gICAgfSk7XG4gIH0pO1xuICBzZXJ2ZXIudW5yZWYoKTtcblxuICBjb25zdCBwb3J0ID0gYXdhaXQgbGlzdGVuT25GcmVlTG9vcGJhY2tQb3J0KHNlcnZlcik7XG4gIHJldHVybiB7XG4gICAgY2xvc2UoKTogdm9pZCB7XG4gICAgICBzZXJ2ZXIuY2xvc2UoKTtcbiAgICB9LFxuICAgIHBvcnRcbiAgfTtcbn1cblxuLyoqXG4gKiBCaW5kcyB0aGUgc2VydmVyIHRvIGFuIGVwaGVtZXJhbCBsb29wYmFjayBwb3J0IGFuZCByZXBvcnRzIHdoaWNoIG9uZSBpdCBnb3QuXG4gKlxuICogQHBhcmFtIHNlcnZlciAtIFRoZSBzZXJ2ZXIgdG8gYmluZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgYXNzaWduZWQgcG9ydC5cbiAqIEB0aHJvd3MgSWYgdGhlIHNlcnZlciByZXBvcnRzIGFuIGVycm9yIGJlZm9yZSBsaXN0ZW5pbmcsIG9yIGJpbmRzIHRvIGEgcGlwZSByYXRoZXIgdGhhbiBhIHBvcnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxpc3Rlbk9uRnJlZUxvb3BiYWNrUG9ydChzZXJ2ZXI6IFNlcnZlcik6IFByb21pc2U8bnVtYmVyPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxudW1iZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXJ2ZXIub25jZSgnZXJyb3InLCByZWplY3QpO1xuICAgIHNlcnZlci5saXN0ZW4oMCwgUEFSRU5UX0xJVkVORVNTX0hPU1QsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKGFkZHJlc3MgPT09IG51bGwgfHwgdHlwZW9mIGFkZHJlc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKCdGYWlsZWQgdG8gZGV0ZXJtaW5lIHRoZSBwYXJlbnQtbGl2ZW5lc3MgcG9ydC4nKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoYWRkcmVzcy5wb3J0KTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiQUFzQ0EsU0FBUyxvQkFBb0I7QUFpQnRCLE1BQU0sdUJBQXVCO0FBaUI3QixTQUFTLGdDQUFnQyxNQUFzQjtBQUNwRSxTQUFPO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsNkJBYW9CLE9BQU8sSUFBSSxDQUFDLE1BQU0sb0JBQW9CO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWVuRTtBQVlBLGVBQXNCLDRCQUEyRDtBQUMvRSxRQUFNLFNBQVMsYUFBYSxDQUFDLFdBQVc7QUFDdEMsV0FBTyxNQUFNO0FBRWIsV0FBTyxHQUFHLFNBQVMsTUFBTTtBQUFBLElBRXpCLENBQUM7QUFBQSxFQUNILENBQUM7QUFDRCxTQUFPLE1BQU07QUFFYixRQUFNLE9BQU8sTUFBTSx5QkFBeUIsTUFBTTtBQUNsRCxTQUFPO0FBQUEsSUFDTCxRQUFjO0FBQ1osYUFBTyxNQUFNO0FBQUEsSUFDZjtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFTQSxlQUFlLHlCQUF5QixRQUFpQztBQUN2RSxTQUFPLElBQUksUUFBZ0IsQ0FBQyxTQUFTLFdBQVc7QUFDOUMsV0FBTyxLQUFLLFNBQVMsTUFBTTtBQUMzQixXQUFPLE9BQU8sR0FBRyxzQkFBc0IsTUFBTTtBQUMzQyxZQUFNLFVBQVUsT0FBTyxRQUFRO0FBQy9CLFVBQUksWUFBWSxRQUFRLE9BQU8sWUFBWSxVQUFVO0FBQ25ELGVBQU8sTUFBTTtBQUNiLGVBQU8sSUFBSSxNQUFNLCtDQUErQyxDQUFDO0FBQ2pFO0FBQUEsTUFDRjtBQUNBLGNBQVEsUUFBUSxJQUFJO0FBQUEsSUFDdEIsQ0FBQztBQUFBLEVBQ0gsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -274,6 +274,18 @@ export declare class DesktopCdpTransport implements ObsidianTransport {
274
274
  * @param actualElectronVersion - The live Electron version, or `undefined` when unreadable.
275
275
  */
276
276
  private applyElectronCompatibility;
277
+ /**
278
+ * Points the owned instance's renderer at this process's liveness socket so it
279
+ * destroys itself if we die without running teardown (see `parent-liveness.ts`).
280
+ *
281
+ * Best-effort by design. A renderer without Node access reports `'unavailable'`
282
+ * and an evaluation failure is logged and swallowed: the watchdog is a backstop
283
+ * for an already-abnormal exit, never a reason to fail an otherwise good launch.
284
+ *
285
+ * @param vaultPath - The vault path to evaluate in.
286
+ * @param parentLivenessPort - The loopback port the renderer should connect back to.
287
+ */
288
+ private armParentLivenessWatchdog;
277
289
  /**
278
290
  * Verifies the running app (asar) version matches the swapped-in pin, storing the
279
291
  * verdict on {@link getAsarFallback}. On a **silent fallback** (the installer ran