@cydm/happy-elves 0.1.0-beta.78 → 0.1.0-beta.79

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.
Files changed (64) hide show
  1. package/apps/cli/dist/commands/daemon.js +3 -6
  2. package/apps/cli/dist/commands/lib/bootstrap-daemon.d.ts +2 -2
  3. package/apps/cli/dist/commands/lib/bootstrap-daemon.js +12 -33
  4. package/apps/cli/dist/commands/lib/bootstrap.js +1 -1
  5. package/apps/cli/dist/commands/lib/doctor.js +1 -32
  6. package/apps/cli/dist/commands/lib/local-daemon.d.ts +11 -40
  7. package/apps/cli/dist/commands/lib/local-daemon.js +123 -157
  8. package/apps/daemon/dist/account-config-lock.d.ts +0 -10
  9. package/apps/daemon/dist/account-config-lock.js +0 -35
  10. package/apps/daemon/dist/args.js +0 -3
  11. package/apps/daemon/dist/cli.js +1 -42
  12. package/apps/daemon/dist/gateway/runtime.js +80 -36
  13. package/apps/daemon/dist/lifecycle/detached-helper-bundle.mjs +943 -4642
  14. package/apps/daemon/dist/lifecycle/helper.d.ts +0 -1
  15. package/apps/daemon/dist/lifecycle/helper.js +3 -35
  16. package/apps/daemon/dist/lifecycle/operation.d.ts +0 -2
  17. package/apps/daemon/dist/lifecycle/operation.js +0 -45
  18. package/apps/daemon/dist/lifecycle/restart.d.ts +0 -1
  19. package/apps/daemon/dist/lifecycle/restart.js +1 -1
  20. package/apps/daemon/dist/lifecycle/runtime.js +0 -19
  21. package/apps/daemon/dist/lifecycle/service.d.ts +5 -19
  22. package/apps/daemon/dist/lifecycle/service.js +8 -82
  23. package/apps/daemon/dist/lifecycle/types.d.ts +1 -1
  24. package/apps/daemon/dist/loop/runner.js +51 -14
  25. package/apps/daemon/dist/memory/flush.js +61 -2
  26. package/apps/daemon/dist/relay/connection.js +1 -1
  27. package/apps/daemon/dist/relay/register.d.ts +2 -4
  28. package/apps/daemon/dist/relay/register.js +2 -24
  29. package/apps/daemon/dist/relay/send.d.ts +11 -0
  30. package/apps/daemon/dist/relay/send.js +68 -0
  31. package/apps/daemon/dist/runtime/session-recovery.d.ts +1 -0
  32. package/apps/daemon/dist/runtime/session-recovery.js +30 -7
  33. package/apps/daemon/dist/session/prompt.d.ts +5 -0
  34. package/apps/daemon/dist/session/prompt.js +47 -7
  35. package/apps/daemon/dist/start.d.ts +0 -19
  36. package/apps/daemon/dist/start.js +46 -84
  37. package/apps/daemon/dist/turn-coordinator.d.ts +34 -1
  38. package/apps/daemon/dist/turn-coordinator.js +151 -5
  39. package/apps/daemon/package.json +1 -1
  40. package/apps/relay/dist/account-http-routes.js +12 -20
  41. package/apps/relay/dist/account-projections.d.ts +0 -1
  42. package/apps/relay/dist/account-projections.js +0 -2
  43. package/apps/relay/dist/db.js +3 -3
  44. package/apps/relay/dist/machine-command-result-handlers.js +7 -10
  45. package/apps/relay/dist/projections.js +1 -4
  46. package/apps/relay/dist/relay-context.js +0 -5
  47. package/apps/relay/dist/types.d.ts +0 -1
  48. package/apps/relay/dist/websocket.js +0 -1
  49. package/build-identity.json +2 -2
  50. package/npm-shrinkwrap.json +2 -2
  51. package/package.json +1 -1
  52. package/packages/client/dist/account-management.js +3 -3
  53. package/packages/client/dist/transport.js +0 -2
  54. package/packages/daemon-service/dist/index.d.ts +14 -0
  55. package/packages/daemon-service/dist/index.js +53 -4
  56. package/packages/shared/dist/account.d.ts +2 -20
  57. package/packages/shared/dist/account.js +1 -2
  58. package/packages/shared/dist/daemon-lifecycle.d.ts +1 -35
  59. package/packages/shared/dist/daemon-lifecycle.js +2 -20
  60. package/packages/shared/dist/protocol-schemas.d.ts +3 -41
  61. package/packages/shared/dist/protocol-schemas.js +1 -2
  62. package/packages/shared/dist/protocol-types.d.ts +1 -2
  63. package/packages/shared/dist/protocol.d.ts +0 -2
  64. package/packages/shared/dist/protocol.js +0 -2
@@ -2,7 +2,7 @@ import { createHash, timingSafeEqual } from "node:crypto";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { daemonLifecycleRequestIdV1Schema, } from "../../../../packages/shared/dist/index.js";
5
- import { assertLocalDaemonRuntimeMatchesConfig, assertLocalDaemonVerified, assertNoPendingEnrollmentAuthority, canonicalRelayUrl, cliErrorFromFetch, CliError, compactText, ControllerClient, configDir, configPath, daemonPidPath, deriveOrchestration, diagnoseInstallation, emitDoctorResult, ensureDaemonRunning, idleSessionStatuses, localDaemonStatus, ok, parsePairingClaimResponse, randomId, readConfig, readDaemonConfig, readDaemonProjectionBaseline, readLocalAuditLog, readRelayJson, redactedDaemonConfig, requirePositional, requireRelayUrl, requireString, showMachine, startDaemonTimeoutMs, stopLocalDaemon, stopSpawnedDaemon, throwRelayHttpError, waitForDaemonReadiness, waitForDaemonSelfReadiness, wantsJson, withAccountConfigTransaction } from "./lib/index.js";
5
+ import { assertLocalDaemonRuntimeMatchesConfig, assertLocalDaemonVerified, assertNoPendingEnrollmentAuthority, canonicalRelayUrl, cliErrorFromFetch, CliError, compactText, ControllerClient, configDir, configPath, daemonPidPath, deriveOrchestration, diagnoseInstallation, emitDoctorResult, ensureDaemonRunning, idleSessionStatuses, localDaemonStatus, ok, parsePairingClaimResponse, randomId, readConfig, readDaemonConfig, readDaemonProjectionBaseline, readLocalAuditLog, readRelayJson, redactedDaemonConfig, requirePositional, requireRelayUrl, requireString, restartDaemonForBootstrap, showMachine, startDaemonTimeoutMs, stopLocalDaemon, stopSpawnedDaemon, throwRelayHttpError, waitForDaemonReadiness, waitForDaemonSelfReadiness, wantsJson, withAccountConfigTransaction } from "./lib/index.js";
6
6
  function positiveLimit(flags, fallback) {
7
7
  const value = flags.limit;
8
8
  if (value === undefined)
@@ -324,12 +324,11 @@ export async function handleDaemon({ domain, action, flags }) {
324
324
  const baseline = client
325
325
  ? await readDaemonProjectionBaseline(client, config.machineId, { timeoutMs: startDaemonTimeoutMs })
326
326
  : undefined;
327
- const daemon = await ensureDaemonRunning(config);
328
- const readiness = await waitForLocalDaemonReadiness(client, config, baseline, daemon, daemon.started);
327
+ const daemon = await restartDaemonForBootstrap(config);
328
+ const readiness = await waitForLocalDaemonReadiness(client, config, baseline, daemon, true);
329
329
  return {
330
330
  ...readiness.local,
331
331
  started: daemon.started,
332
- ...(daemon.autostartNeedsAttention ? { needsAttention: daemon.autostartNeedsAttention } : {}),
333
332
  machineId: readiness.machine?.id ?? config.machineId,
334
333
  relayAuthenticated: readiness.relayAuthenticated,
335
334
  ...(readiness.relayAuthenticated === "verified" ? { online: true } : {}),
@@ -519,8 +518,6 @@ function writeHumanDaemonStartOutput(data) {
519
518
  if (data.relayAuthenticated === "unverified") {
520
519
  console.log("Local daemon identity is ready; relay authentication was not verified because this host has no matching Device credential.");
521
520
  }
522
- if (data.needsAttention)
523
- console.log(`Automatic startup needs attention: ${data.needsAttention}`);
524
521
  console.log("This command manages only the paired background daemon; it does not open a browser page.");
525
522
  console.log("For setup or browser onboarding, run: happy-elves start");
526
523
  }
@@ -10,7 +10,6 @@ export declare function ensureDaemonRunning(expectedConfig: DaemonConfig, cwd?:
10
10
  startedPid?: number;
11
11
  startedHandle?: SpawnedDaemonHandle;
12
12
  committedConfigMayBeInUse?: boolean;
13
- autostartNeedsAttention?: string;
14
13
  }>;
15
14
  type BootstrapDaemonRestartOptions = {
16
15
  readStatus?: typeof localDaemonStatus;
@@ -27,7 +26,8 @@ type BootstrapDaemonRestartOptions = {
27
26
  * always loads the currently installed package before the browser opens.
28
27
  *
29
28
  * The lower-level `ensureDaemonRunning()` deliberately remains idempotent for
30
- * `happy-elves daemon start`, enrollment rollback, and service recovery.
29
+ * enrollment rollback and internal recovery flows. Public `start` commands
30
+ * use this explicit restart boundary so they load the installed package.
31
31
  */
32
32
  export declare function restartDaemonForBootstrap(expectedConfig: DaemonConfig, cwd?: string, options?: BootstrapDaemonRestartOptions): Promise<Awaited<ReturnType<typeof ensureDaemonRunning>> & {
33
33
  restarted: boolean;
@@ -3,7 +3,7 @@ import { daemonRuntimeConfigFingerprint } from "../../../../../packages/shared/d
3
3
  import { CliError } from "../../errors.js";
4
4
  import { startDaemonTimeoutMs } from "./paths.js";
5
5
  import { readDaemonConfig } from "./config.js";
6
- import { assertLocalDaemonRuntimeMatchesConfig, assertLocalDaemonVerified, inspectLocalDaemonRuntime, ensureRunningDaemonAutostart, localDaemonStatus, readLocalDaemonPidIdentity, spawnDaemonStartTracked, stopLocalDaemon, stopSpawnedDaemon, } from "./local-daemon.js";
6
+ import { assertLocalDaemonRuntimeMatchesConfig, assertLocalDaemonVerified, inspectLocalDaemonRuntime, localDaemonStatus, readLocalDaemonPidIdentity, spawnDaemonStartTracked, stopLocalDaemon, stopSpawnedDaemon, } from "./local-daemon.js";
7
7
  const committedConfigMayBeInUseErrors = new WeakSet();
8
8
  export function startFailureMayUseCommittedConfig(error) {
9
9
  return Boolean(error && typeof error === "object" && committedConfigMayBeInUseErrors.has(error));
@@ -34,26 +34,16 @@ export async function ensureDaemonRunning(expectedConfig, cwd = process.cwd()) {
34
34
  const owner = await readLocalDaemonPidIdentity();
35
35
  if (!owner.record)
36
36
  throw new CliError("Verified daemon owner identity is missing.", "DAEMON_PID_INVALID");
37
- const autostart = await ensureRunningDaemonAutostart();
38
- const confirmedOwner = await readLocalDaemonPidIdentity();
39
- if (!confirmedOwner.record ||
40
- confirmedOwner.record.pid !== owner.record.pid ||
41
- confirmedOwner.record.instanceNonce !== owner.record.instanceNonce) {
42
- throw committedConfigInUseError("The verified daemon owner changed while automatic startup was being inspected. No replacement process was started.");
43
- }
44
37
  return {
45
38
  local: current,
46
39
  instanceGeneration: owner.record.instanceNonce,
47
40
  started: false,
48
41
  committedConfigMayBeInUse: true,
49
- ...(autostart.state === "needs-attention"
50
- ? { autostartNeedsAttention: autostart.message }
51
- : {}),
52
42
  };
53
43
  }
54
44
  const handle = await spawnDaemonStartTracked([], cwd, daemonRuntimeConfigFingerprint(expectedConfig));
55
- let startedPid = handle.pid || undefined;
56
- if (handle.kind === "child" && !startedPid)
45
+ const startedPid = handle.pid || undefined;
46
+ if (!startedPid)
57
47
  throw new CliError("Daemon failed to start.", "DAEMON_START_FAILED");
58
48
  try {
59
49
  const spawnResult = await handle.spawnResult;
@@ -76,28 +66,16 @@ export async function ensureDaemonRunning(expectedConfig, cwd = process.cwd()) {
76
66
  }
77
67
  if (local.running) {
78
68
  const owner = await readLocalDaemonPidIdentity();
79
- const ownOwner = owner.record?.instanceNonce === handle.instanceNonce &&
80
- (handle.kind === "service" || owner.record.pid === handle.pid);
81
- if (ownOwner && owner.record && handle.kind === "service") {
82
- handle.pid = owner.record.pid;
83
- handle.observedOwner = {
84
- pid: owner.record.pid,
85
- instanceNonce: owner.record.instanceNonce,
86
- startedAt: owner.record.startedAt,
87
- };
88
- startedPid = owner.record.pid;
89
- }
69
+ const ownOwner = owner.record?.instanceNonce === handle.instanceNonce && owner.record.pid === handle.pid;
90
70
  const runtime = await inspectLocalDaemonRuntime(expectedConfig);
91
71
  if (!ownOwner) {
92
72
  competingOwnerObserved = true;
93
73
  if (runtime.state === "match") {
94
- if (handle.kind === "child") {
95
- try {
96
- await stopSpawnedDaemon(handle);
97
- }
98
- catch (cleanupError) {
99
- throw markCommittedConfigMayBeInUse(new CliError(`A matching daemon became owner, but this start attempt could not settle its own child: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`, "DAEMON_START_CLEANUP_FAILED"));
100
- }
74
+ try {
75
+ await stopSpawnedDaemon(handle);
76
+ }
77
+ catch (cleanupError) {
78
+ throw markCommittedConfigMayBeInUse(new CliError(`A matching daemon became owner, but this start attempt could not settle its own child: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`, "DAEMON_START_CLEANUP_FAILED"));
101
79
  }
102
80
  const confirmedLocal = await localDaemonStatus();
103
81
  try {
@@ -158,7 +136,7 @@ export async function ensureDaemonRunning(expectedConfig, cwd = process.cwd()) {
158
136
  // A missing or stale marker is a bounded startup window. The daemon
159
137
  // publishes its owner-bound marker atomically immediately after PID v2.
160
138
  }
161
- if (handle.kind === "child" && !competingOwnerPending &&
139
+ if (!competingOwnerPending &&
162
140
  (handle.child.exitCode !== null || handle.child.signalCode !== null)) {
163
141
  throw new CliError("Daemon exited during startup.", "DAEMON_START_FAILED");
164
142
  }
@@ -189,7 +167,8 @@ export async function ensureDaemonRunning(expectedConfig, cwd = process.cwd()) {
189
167
  * always loads the currently installed package before the browser opens.
190
168
  *
191
169
  * The lower-level `ensureDaemonRunning()` deliberately remains idempotent for
192
- * `happy-elves daemon start`, enrollment rollback, and service recovery.
170
+ * enrollment rollback and internal recovery flows. Public `start` commands
171
+ * use this explicit restart boundary so they load the installed package.
193
172
  */
194
173
  export async function restartDaemonForBootstrap(expectedConfig, cwd = process.cwd(), options = {}) {
195
174
  const readStatus = options.readStatus ?? localDaemonStatus;
@@ -290,7 +290,7 @@ export async function startBootstrap(flags) {
290
290
  return;
291
291
  }
292
292
  const { daemonBefore, controllerState, daemonState, daemon, machine, invite, daemonProcessNeedsAttention } = prepared;
293
- const daemonNeedsAttention = daemonProcessNeedsAttention ?? daemon.autostartNeedsAttention;
293
+ const daemonNeedsAttention = daemonProcessNeedsAttention;
294
294
  await reconcileSatisfiedDeviceRecoveryPending(daemonState.config, controllerState.config);
295
295
  const data = {
296
296
  relayUrl: controllerState.config.relayUrl,
@@ -5,7 +5,7 @@ import { daemonRuntimeConfigFingerprint, parseDaemonRuntimeIdentity, } from "../
5
5
  import { CliError } from "../../errors.js";
6
6
  import { CliExit } from "./cli-exit.js";
7
7
  import { canonicalRelayUrl, redactedControllerConfig, redactedDaemonConfig, requireRelayUrl, withAccountConfigTransaction, } from "./config.js";
8
- import { localDaemonAutostartStatus, localDaemonStatus, readLocalDaemonPidIdentity, } from "./local-daemon.js";
8
+ import { localDaemonStatus, readLocalDaemonPidIdentity, } from "./local-daemon.js";
9
9
  import { ok, wantsJson, writeError } from "./json.js";
10
10
  import { configDir, configPath, daemonRuntimeIdentityPath } from "./paths.js";
11
11
  import { relayHealth } from "./relay-http.js";
@@ -50,29 +50,6 @@ export async function diagnoseInstallation(mode = "controller", requestedRelay)
50
50
  });
51
51
  const runtimeIdentity = await inspectRuntimeIdentity(local.running, daemon);
52
52
  checks.push(runtimeIdentity.check);
53
- try {
54
- const autostart = await localDaemonAutostartStatus();
55
- const needsRepair = autostart.state === "needs-attention";
56
- checks.push({
57
- name: "daemon-automatic-startup",
58
- ok: !needsRepair,
59
- message: autostart.state === "running"
60
- ? "Running"
61
- : autostart.state === "installed"
62
- ? "Installed"
63
- : autostart.state === "unsupported"
64
- ? "Unsupported for this installation"
65
- : "Needs repair",
66
- details: autostart,
67
- });
68
- }
69
- catch (error) {
70
- checks.push({
71
- name: "daemon-automatic-startup",
72
- ok: false,
73
- message: diagnosticMessage(error),
74
- });
75
- }
76
53
  const configInvalid = controllerState === "invalid" || daemonState === "invalid";
77
54
  const controllerRecoveryRequired = Boolean(daemon) &&
78
55
  (controllerState === "missing" || controllerState === "recovery" || daemonState === "recovery" || splitBrain);
@@ -325,8 +302,6 @@ function firstFailureCode(checks) {
325
302
  return "CONFIG_MISSING_OR_INVALID";
326
303
  if (failed.name === "daemon-process")
327
304
  return "DAEMON_NOT_RUNNING";
328
- if (failed.name === "daemon-automatic-startup")
329
- return "DAEMON_AUTOSTART_REPAIR_REQUIRED";
330
305
  return "DOCTOR_ISSUES_FOUND";
331
306
  }
332
307
  function doctorFailureMessage(code) {
@@ -345,9 +320,6 @@ function doctorFailureMessage(code) {
345
320
  if (code === "CONFIG_INVALID") {
346
321
  return "A controller or daemon configuration file is malformed or unsafe. No credential was replaced; inspect the named failed check before attempting recovery.";
347
322
  }
348
- if (code === "DAEMON_AUTOSTART_REPAIR_REQUIRED") {
349
- return "This Daemon is usable now, but automatic startup needs repair. Open Settings > Daemons and choose Repair automatic startup.";
350
- }
351
323
  return "Happy Elves doctor found issues. No configuration or process state was changed.";
352
324
  }
353
325
  function doctorRecoveryGuidance(code) {
@@ -381,9 +353,6 @@ function doctorRecoveryGuidance(code) {
381
353
  if (code === "CONFIG_INVALID") {
382
354
  return "Inspect the controller-config and daemon-config checks above. Preserve the files before using an explicit recovery command; start will not overwrite them.";
383
355
  }
384
- if (code === "DAEMON_AUTOSTART_REPAIR_REQUIRED") {
385
- return "Open Settings > Daemons and choose Repair automatic startup. Happy Elves will only repair its fixed user-level service.";
386
- }
387
356
  return "Review the failed checks above before changing credentials or restarting the daemon.";
388
357
  }
389
358
  function diagnosticMessage(error) {
@@ -1,6 +1,5 @@
1
1
  import { type ChildProcess } from "node:child_process";
2
2
  import { isDaemonProcessAlive, type DaemonPidIdentity, type DaemonRuntimeIdentityV1 } from "../../../../../packages/shared/dist/node/daemon-process.js";
3
- import { inspectDaemonAutostartProjection, uninstallOwnedDaemonService, type DaemonServiceSpec } from "../../../../../packages/daemon-service/dist/index.js";
4
3
  import type { DaemonConfig } from "./types.js";
5
4
  type LocalDaemonState = "stopped" | "running" | "unverified";
6
5
  export type LocalDaemonStatus = {
@@ -28,26 +27,12 @@ type SpawnedChildDaemonHandle = {
28
27
  signal: NodeJS.Signals | null;
29
28
  }>;
30
29
  };
31
- type SpawnedManagedDaemonHandle = {
32
- kind: "service";
30
+ type DaemonOwnerFence = {
33
31
  pid: number;
34
32
  instanceNonce: string;
35
- service: DaemonServiceSpec;
36
- installedFresh: boolean;
37
- spawnResult: Promise<{
38
- spawned: true;
39
- } | {
40
- spawned: false;
41
- error: Error;
42
- }>;
43
- observedOwner?: {
44
- pid: number;
45
- instanceNonce: string;
46
- startedAt: number;
47
- };
33
+ startedAt: number;
48
34
  };
49
- type DaemonOwnerFence = NonNullable<SpawnedManagedDaemonHandle["observedOwner"]>;
50
- export type SpawnedDaemonHandle = SpawnedChildDaemonHandle | SpawnedManagedDaemonHandle;
35
+ export type SpawnedDaemonHandle = SpawnedChildDaemonHandle;
51
36
  export type LocalDaemonRuntimeInspection = {
52
37
  state: "match";
53
38
  identity: DaemonRuntimeIdentityV1;
@@ -65,30 +50,17 @@ export type LocalDaemonRuntimeInspection = {
65
50
  export declare const isPidAlive: typeof isDaemonProcessAlive;
66
51
  export declare function readLocalDaemonPidIdentity(): Promise<DaemonPidIdentity>;
67
52
  export declare function localDaemonStatus(): Promise<LocalDaemonStatus>;
68
- export declare function localDaemonAutostartStatus(): Promise<import("../../../../../packages/daemon-service/dist/index.js").DaemonAutostartProjection>;
69
- export type RunningDaemonAutostartResult = {
70
- state: "installed";
71
- } | {
72
- state: "unsupported";
73
- } | {
74
- state: "needs-attention";
75
- code: string;
76
- message: string;
77
- };
78
- /**
79
- * Inspect automatic startup without starting, stopping, registering, or
80
- * replacing anything while a healthy Daemon owns the lifetime lease. In
81
- * particular, registering a launchd RunAtLoad job here would briefly launch a
82
- * second child and could arm KeepAlive retries. Missing/repairable service
83
- * state is therefore projected for the next controlled restart or UI Repair.
84
- */
85
- export declare function ensureRunningDaemonAutostart(options?: {
86
- inspectAutostart?: typeof inspectDaemonAutostartProjection;
87
- }): Promise<RunningDaemonAutostartResult>;
88
53
  export declare function inspectLocalDaemonRuntime(config: DaemonConfig): Promise<LocalDaemonRuntimeInspection>;
89
54
  export declare function assertLocalDaemonRuntimeMatchesConfig(config: DaemonConfig): Promise<void>;
90
55
  export declare function assertLocalDaemonVerified(status: LocalDaemonStatus): void;
91
- export declare function spawnDaemonStartTracked(args: string[], cwd?: string, expectedConfigFingerprint?: string): Promise<SpawnedDaemonHandle>;
56
+ export declare function spawnDaemonStartTracked(args: string[], cwd?: string, _expectedConfigFingerprint?: string): Promise<SpawnedDaemonHandle>;
57
+ /**
58
+ * A direct replacement is deliberately a child of the invoking CLI rather
59
+ * than a launchd/systemd/Task process. Preserve the caller's complete
60
+ * provider environment (notably Homebrew's PATH) and override only the
61
+ * isolated Happy Elves home it is authorized to own.
62
+ */
63
+ export declare function directDaemonChildEnvironment(parentEnvironment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
92
64
  /**
93
65
  * Stop only the exact child created by the current `start` attempt. A PID-file
94
66
  * owner that appeared concurrently is never signalled or removed.
@@ -96,7 +68,6 @@ export declare function spawnDaemonStartTracked(args: string[], cwd?: string, ex
96
68
  export declare function stopSpawnedDaemon(handle: SpawnedDaemonHandle, timeoutMs?: number, options?: {
97
69
  readIdentity?: typeof readLocalDaemonPidIdentity;
98
70
  stopLocal?: typeof stopLocalDaemon;
99
- uninstallService?: typeof uninstallOwnedDaemonService;
100
71
  }): Promise<void>;
101
72
  export declare function stopLocalDaemon(timeoutMs?: number, expectedOwner?: DaemonOwnerFence): Promise<LocalDaemonStatus & {
102
73
  stopped: boolean;