@north-light/api 0.3.590 → 0.3.592

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.
@@ -122,6 +122,11 @@ export declare class DaemonExitedBeforeReadyError extends Error {
122
122
  readonly stderrTail: string;
123
123
  constructor(message: string, stderrTail: string);
124
124
  }
125
+ /** The daemon's launch command could not be resolved, so no child was ever
126
+ * started — a standing failure that waiting longer cannot fix. */
127
+ export declare class DaemonLaunchError extends Error {
128
+ constructor(cause: unknown);
129
+ }
125
130
  /** A live daemon has bound its repair socket but cannot serve normal work
126
131
  * until its corpus migration succeeds. */
127
132
  export declare class DaemonStartupBlockedError extends Error {
@@ -200,7 +205,8 @@ export interface EnsureDaemonDeps {
200
205
  spawnDaemon?: () => Promise<SpawnDaemonResult>;
201
206
  now?: () => number;
202
207
  }
203
- /** Why the daemon this process autostarted died before becoming ready, or
208
+ /** Why the daemon this process autostarted died before becoming ready, or why
209
+ * its launch command could not be resolved (no daemon was started), or
204
210
  * undefined while it is starting, running, or exited cleanly (a clean exit may
205
211
  * be a lost singleton race, so only a non-zero/signal exit counts). A client
206
212
  * waiting for that daemon polls this so a startup failure ends the wait now
@@ -210,6 +216,7 @@ export declare function daemonAutostartStartupFailure(): string | undefined;
210
216
  * autostart is suppressed for this invocation, while `crtr sys join` holds
211
217
  * the join lock (see core/directory/join-lock.ts), while an attempt is in flight,
212
218
  * or while backing off from a recent failure.
213
- * Silently swallows spawn errors (the canvas still works without the daemon;
214
- * nodes just won't be auto-revived). */
219
+ * Does not throw: a spawn error is recorded, and a launch or early-exit failure
220
+ * is reported through `daemonAutostartStartupFailure()` so a waiting client
221
+ * fails with it. */
215
222
  export declare function ensureDaemon(deps?: EnsureDaemonDeps): void;
@@ -290,6 +290,14 @@ export class DaemonExitedBeforeReadyError extends Error {
290
290
  this.stderrTail = stderrTail;
291
291
  }
292
292
  }
293
+ /** The daemon's launch command could not be resolved, so no child was ever
294
+ * started — a standing failure that waiting longer cannot fix. */
295
+ export class DaemonLaunchError extends Error {
296
+ constructor(cause) {
297
+ super(cause instanceof Error ? cause.message : String(cause), { cause });
298
+ this.name = 'DaemonLaunchError';
299
+ }
300
+ }
293
301
  /** A live daemon has bound its repair socket but cannot serve normal work
294
302
  * until its corpus migration succeeds. */
295
303
  export class DaemonStartupBlockedError extends Error {
@@ -544,7 +552,9 @@ export async function spawnDaemon(opts = {}) {
544
552
  // in macOS Full Disk Access, not "node" (see branded-host). NOTE: when crtrd
545
553
  // is launchd-owned, the plist's ProgramArguments must point at the branded
546
554
  // binary too — this path only covers a manual `crtr sys daemon start`.
547
- const launchArgs = await resolveDaemonLaunch();
555
+ const launchArgs = await resolveDaemonLaunch().catch((error) => {
556
+ throw new DaemonLaunchError(error);
557
+ });
548
558
  // The one spawn point every start reaches (autostart, `sys daemon start`, a handover successor): an
549
559
  // autostart begun before a join took its lock lands here after it, and must not start a daemon.
550
560
  if (opts.waitForJoinLock === true)
@@ -671,7 +681,8 @@ export function resetDaemonAutostart() {
671
681
  autostartFailures = 0;
672
682
  autostartNextAttemptAt = 0;
673
683
  }
674
- /** Why the daemon this process autostarted died before becoming ready, or
684
+ /** Why the daemon this process autostarted died before becoming ready, or why
685
+ * its launch command could not be resolved (no daemon was started), or
675
686
  * undefined while it is starting, running, or exited cleanly (a clean exit may
676
687
  * be a lost singleton race, so only a non-zero/signal exit counts). A client
677
688
  * waiting for that daemon polls this so a startup failure ends the wait now
@@ -683,8 +694,9 @@ export function daemonAutostartStartupFailure() {
683
694
  * autostart is suppressed for this invocation, while `crtr sys join` holds
684
695
  * the join lock (see core/directory/join-lock.ts), while an attempt is in flight,
685
696
  * or while backing off from a recent failure.
686
- * Silently swallows spawn errors (the canvas still works without the daemon;
687
- * nodes just won't be auto-revived). */
697
+ * Does not throw: a spawn error is recorded, and a launch or early-exit failure
698
+ * is reported through `daemonAutostartStartupFailure()` so a waiting client
699
+ * fails with it. */
688
700
  export function ensureDaemon(deps = {}) {
689
701
  const running = deps.isDaemonRunning ?? isDaemonRunning;
690
702
  const spawn = deps.spawnDaemon ?? spawnDaemon;
@@ -711,11 +723,9 @@ export function ensureDaemon(deps = {}) {
711
723
  autostartFailures = 0;
712
724
  autostartNextAttemptAt = 0;
713
725
  }, (error) => {
714
- if (error instanceof DaemonExitedBeforeReadyError) {
726
+ if (error instanceof DaemonExitedBeforeReadyError || error instanceof DaemonLaunchError) {
715
727
  autostartStartupFailure = error.message;
716
728
  }
717
- // Intentionally silent — a missing dist/daemon/crtrd-cli.js (dev mode,
718
- // pre-build) must not break the calling command.
719
729
  autostartFailures += 1;
720
730
  autostartNextAttemptAt = now() + autostartBackoffMs(autostartFailures);
721
731
  }).finally(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/api",
3
- "version": "0.3.590",
3
+ "version": "0.3.592",
4
4
  "description": "Typed crtrd /v1 API contract — DTOs, route builders, the error contract, the CrtrClient, and the command-plugin manifest format. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "main": "./dist/api/index.js",