@orkestrel/process 0.0.9 → 0.0.11

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.
@@ -1,23 +1,24 @@
1
1
  import { Buffer as Buffer_2 } from 'node:buffer';
2
- import { DetachOptions } from '@orkestrel/process';
3
- import { EmitterInterface } from '@orkestrel/emitter';
4
- import { ExecutableOptions } from '@orkestrel/process';
5
- import { ExecuteInput } from '@orkestrel/process';
6
- import { ExecuteOptions } from '@orkestrel/process';
7
- import { ExecuteResult } from '@orkestrel/process';
8
- import { ExecuteSyncOptions } from '@orkestrel/process';
9
- import { ProcessCommand } from '@orkestrel/process';
10
- import { ProcessEventMap } from '@orkestrel/process';
11
- import { ProcessExit } from '@orkestrel/process';
12
- import { ProcessInterface } from '@orkestrel/process';
13
- import { ProcessManagerEventMap } from '@orkestrel/process';
14
- import { ProcessManagerInterface } from '@orkestrel/process';
15
- import { ProcessManagerOptions } from '@orkestrel/process';
16
- import { ProcessOptions } from '@orkestrel/process';
17
- import { SessionEventMap } from '@orkestrel/process';
18
- import { SessionInterface } from '@orkestrel/process';
19
- import { SessionOptions } from '@orkestrel/process';
20
- import { SpawnInput } from '@orkestrel/process';
2
+ import type { DetachOptions } from '@orkestrel/process';
3
+ import type { EmitterInterface } from '@orkestrel/emitter';
4
+ import type { ExecutableOptions } from '@orkestrel/process';
5
+ import type { ExecuteInput } from '@orkestrel/process';
6
+ import type { ExecuteOptions } from '@orkestrel/process';
7
+ import type { ExecuteResult } from '@orkestrel/process';
8
+ import type { ExecuteSyncOptions } from '@orkestrel/process';
9
+ import type { ProcessCommand } from '@orkestrel/process';
10
+ import type { ProcessEventMap } from '@orkestrel/process';
11
+ import type { ProcessExit } from '@orkestrel/process';
12
+ import type { ProcessInterface } from '@orkestrel/process';
13
+ import type { ProcessManagerEventMap } from '@orkestrel/process';
14
+ import type { ProcessManagerInterface } from '@orkestrel/process';
15
+ import type { ProcessManagerOptions } from '@orkestrel/process';
16
+ import type { ProcessOptions } from '@orkestrel/process';
17
+ import type { Readable } from 'node:stream';
18
+ import type { SessionEventMap } from '@orkestrel/process';
19
+ import type { SessionInterface } from '@orkestrel/process';
20
+ import type { SessionOptions } from '@orkestrel/process';
21
+ import type { SpawnInput } from '@orkestrel/process';
21
22
 
22
23
  /**
23
24
  * Builds the executable candidates an explicit platform would search.
@@ -143,26 +144,37 @@ export declare function buildSpawn(command: ProcessCommand, options?: Executable
143
144
  export declare function captureChunk(chunk: unknown, room: number): Buffer_2 | undefined;
144
145
 
145
146
  /**
146
- * Creates one supervised child process.
147
+ * Creates one supervised child process and returns it as a {@link ProcessInterface}, so a caller
148
+ * holds the published contract rather than the `Process` class.
147
149
  *
148
150
  * @param options - Command, workspace, termination, evidence, stdin, and observation settings
149
151
  * @returns The launched {@link ProcessInterface}
150
152
  *
151
- * @example
153
+ * @example Supervise a child and read its lines
152
154
  * ```ts
153
155
  * import { createProcess } from '@orkestrel/process/server'
154
156
  *
155
157
  * const child = createProcess({
156
- * command: { file: 'node', arguments: ['--version'] },
158
+ * command: { file: 'node', arguments: ['-e', 'console.log("ready"); console.log("done")'] },
157
159
  * workspace: process.cwd(),
158
- * grace: 5000,
160
+ * grace: 5_000, // POSIX only: the window between SIGTERM and SIGKILL
159
161
  * })
162
+ *
163
+ * const lines: string[] = []
164
+ * for await (const line of child.lines) lines.push(line)
165
+ * lines // ['ready', 'done']
166
+ *
167
+ * const exit = await child.exit
168
+ * exit.code // 0
169
+ * await child.destroy()
160
170
  * ```
161
171
  */
162
172
  export declare function createProcess(options: ProcessOptions): ProcessInterface;
163
173
 
164
174
  /**
165
- * Creates one keyed registry of supervised child processes.
175
+ * Creates one empty keyed registry of supervised child processes and returns it as a
176
+ * {@link ProcessManagerInterface}, so a caller holds the published contract rather than the
177
+ * `ProcessManager` class.
166
178
  *
167
179
  * @param options - Initial fleet-level observation hooks and listener-error handling
168
180
  * @returns The {@link ProcessManagerInterface} registry
@@ -177,7 +189,8 @@ export declare function createProcess(options: ProcessOptions): ProcessInterface
177
189
  export declare function createProcessManager(options?: ProcessManagerOptions): ProcessManagerInterface;
178
190
 
179
191
  /**
180
- * Creates one raw byte session over a supervised child process.
192
+ * Creates one raw byte session over a supervised child process and returns it as a
193
+ * {@link SessionInterface}, so a caller holds the published contract rather than the `Session` class.
181
194
  *
182
195
  * @param options - Command, workspace, termination, evidence, stdin, and observation settings
183
196
  * @returns The launched {@link SessionInterface}
@@ -301,14 +314,14 @@ export declare function formatCommand(command: ProcessCommand): string;
301
314
  * initiated against a pid the host may have reused.
302
315
  *
303
316
  * @param child - The child boundary
304
- * @returns True when the process has exited; false while it is live
317
+ * @returns True if the process has exited; false otherwise
305
318
  *
306
319
  * @example
307
320
  * ```ts
308
321
  * isExited({ exitCode: 0, signalCode: null }) // true
309
322
  * ```
310
323
  */
311
- export declare function isExited(child: Pick<ProcessChild, 'exitCode' | 'signalCode'>): boolean;
324
+ export declare function isExited(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode'>): boolean;
312
325
 
313
326
  /**
314
327
  * Checks whether a path names a regular file.
@@ -318,7 +331,7 @@ export declare function isExited(child: Pick<ProcessChild, 'exitCode' | 'signalC
318
331
  * command. An unreadable or malformed path reports `false` rather than throwing.
319
332
  *
320
333
  * @param target - The absolute or relative path to inspect
321
- * @returns True when the path resolves to a regular file; false otherwise
334
+ * @returns True if the path resolves to a regular file; false otherwise
322
335
  *
323
336
  * @example
324
337
  * ```ts
@@ -347,7 +360,7 @@ export declare function isFile(target: string): boolean;
347
360
  * killProcess(child, 'SIGTERM')
348
361
  * ```
349
362
  */
350
- export declare function killProcess(child: Pick<ProcessChild, 'pid' | 'kill'>, signal: NodeJS.Signals): void;
363
+ export declare function killProcess(child: Pick<ProcessChildInterface, 'pid' | 'kill'>, signal: NodeJS.Signals): void;
351
364
 
352
365
  /**
353
366
  * Kills one Windows process tree through `taskkill`.
@@ -361,7 +374,7 @@ export declare function killProcess(child: Pick<ProcessChild, 'pid' | 'kill'>, s
361
374
  *
362
375
  * @param pid - The root process id of the tree to end
363
376
  * @param timeout - The milliseconds the utility is given before it is killed
364
- * @returns True when the utility reported success; false when it failed, was unavailable, or was cut off
377
+ * @returns True if the utility reported success; false otherwise (it failed, was unavailable, or was cut off)
365
378
  *
366
379
  * @example
367
380
  * ```ts
@@ -408,7 +421,8 @@ export declare function mergeEnvironment(isolated: boolean, base?: Readonly<Reco
408
421
  export declare function mergePlatformEnvironment(platform: NodeJS.Platform, parent: Readonly<Record<string, string | undefined>>, isolated: boolean, base?: Readonly<Record<string, string | undefined>>, override?: Readonly<Record<string, string | undefined>>): NodeJS.ProcessEnv;
409
422
 
410
423
  /**
411
- * Supervises one child while keeping every observation channel aligned at termination.
424
+ * Supervises one child, frames its standard output into lines under a bounded backlog, and keeps
425
+ * every observation channel aligned at termination.
412
426
  *
413
427
  * @remarks
414
428
  * The child's ending and the supervision's ending are distinct. `pid`, `code`, and `signal` read
@@ -441,34 +455,34 @@ export declare function mergePlatformEnvironment(platform: NodeJS.Platform, pare
441
455
  export declare class Process implements ProcessInterface {
442
456
  #private;
443
457
  /**
444
- * Spawn one child process and begin stream capture.
458
+ * Spawns one child process and begins stream capture.
445
459
  *
446
460
  * @param options - Command, workspace, termination, capture, stdin, and observation settings
447
461
  * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
448
462
  */
449
463
  constructor(options: ProcessOptions);
450
- /** The host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
464
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
451
465
  get pid(): number | undefined;
452
- /** The exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
466
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
453
467
  get code(): number | null;
454
- /** The terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
468
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
455
469
  get signal(): string | null;
456
- /** The typed lifecycle observation surface. */
470
+ /** Holds the typed lifecycle observation surface. */
457
471
  get emitter(): EmitterInterface<ProcessEventMap>;
458
- /** The captured stdout lines, in arrival order, ending after queued lines at the terminal moment. */
472
+ /** Yields the captured stdout lines, in arrival order, ending after queued lines at the terminal moment. */
459
473
  get lines(): AsyncIterable<string>;
460
- /** The decoded byte-bounded stderr tail, frozen at the terminal moment. */
474
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
461
475
  get evidence(): string;
462
- /** True when the `lines` stream omitted output after a retention bound was reached. */
476
+ /** Reports whether the `lines` stream omitted output after a retention bound was reached. */
463
477
  get truncated(): boolean;
464
- /** True after the terminal moment arrived and `exit` settled. */
478
+ /** Reports whether the terminal moment arrived and `exit` settled. */
465
479
  get settled(): boolean;
466
- /** True after termination began, including after the terminal moment. */
480
+ /** Reports whether termination began, including after the terminal moment. */
467
481
  get stopping(): boolean;
468
- /** The terminal child state, observed once after stream close or the drain cutoff. */
482
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
469
483
  get exit(): Promise<ProcessExit>;
470
484
  /**
471
- * Write one line to the open standard-input channel.
485
+ * Writes one line to the open standard-input channel.
472
486
  *
473
487
  * @remarks
474
488
  * Never rejects. `true` means the host accepted the bytes without reporting a fault; it does not
@@ -482,7 +496,7 @@ export declare class Process implements ProcessInterface {
482
496
  * for bytes the package is about to discard.
483
497
  *
484
498
  * @param text - The line text without its trailing newline
485
- * @returns True when the host accepted the bytes without reporting a fault; false when the channel was closed, destroyed, ended, failed, or remained unconfirmed through `delivery`
499
+ * @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
486
500
  */
487
501
  send(text: string): Promise<boolean>;
488
502
  /**
@@ -494,7 +508,7 @@ export declare class Process implements ProcessInterface {
494
508
  * and settles `exit` when they remain open. A cutoff reached before the native exit reports the
495
509
  * `code` and `signal` the host had recorded by then, which is `null` for a child still running.
496
510
  *
497
- * @returns True when the child's native exit was observed; false when the confirmation deadline elapsed without it
511
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
498
512
  */
499
513
  stop(): Promise<boolean>;
500
514
  /**
@@ -509,15 +523,7 @@ export declare class Process implements ProcessInterface {
509
523
  }
510
524
 
511
525
  /**
512
- * The Node-side contracts of `@orkestrel/process/server`.
513
- *
514
- * @remarks
515
- * The host-independent contracts live in `@orkestrel/process`. This module declares only what a
516
- * Node child process boundary requires, which the published contracts cannot express without
517
- * naming `node:child_process` types.
518
- */
519
- /**
520
- * The child boundary the termination helpers drive.
526
+ * Represents the child boundary the termination helpers drive.
521
527
  *
522
528
  * @remarks
523
529
  * A `ChildProcess` satisfies this structurally, and so does any object carrying the same
@@ -531,30 +537,42 @@ export declare class Process implements ProcessInterface {
531
537
  * the route that reaches it: `killProcess` signals the negated `pid` first and falls back to `kill`
532
538
  * when the host reports that no group owns that pid.
533
539
  */
534
- export declare interface ProcessChild {
535
- /** The process id the host assigned, or `undefined` when the spawn never produced one. */
540
+ export declare interface ProcessChildInterface {
541
+ /** Holds the process id the host assigned, or `undefined` when the spawn never produced one. */
536
542
  readonly pid?: number | undefined;
537
- /** The exit code, or `null` while the process is live or a signal ended it. */
543
+ /** Holds the exit code, or `null` while the process is live or a signal ended it. */
538
544
  readonly exitCode: number | null;
539
- /** The terminating signal name, or `null` while the process is live or it exited on its own. */
545
+ /** Holds the terminating signal name, or `null` while the process is live or it exited on its own. */
540
546
  readonly signalCode: string | null;
541
547
  /**
542
- * Deliver one signal to the process.
548
+ * Delivers one signal to the process.
543
549
  *
544
550
  * @param signal - The signal to deliver
545
- * @returns True when the host accepted the signal; false otherwise
551
+ * @returns True if the host accepted the signal; false otherwise
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * const accepted = child.kill('SIGTERM')
556
+ * accepted // true
557
+ * ```
546
558
  */
547
559
  kill(signal: NodeJS.Signals): boolean;
548
560
  /**
549
- * Register a one-shot listener for the native exit or stream close.
561
+ * Registers a one-shot listener for the native exit or stream close.
550
562
  *
551
563
  * @param event - The `exit` or `close` event name
552
564
  * @param listener - The listener invoked after the selected event
553
565
  * @returns Whatever the emitter returns, which the helpers ignore
566
+ *
567
+ * @example
568
+ * ```ts
569
+ * const settle = (): void => undefined
570
+ * child.once('exit', settle)
571
+ * ```
554
572
  */
555
573
  once(event: 'exit' | 'close', listener: () => void): unknown;
556
574
  /**
557
- * Release one previously registered exit or close listener.
575
+ * Releases one previously registered exit or close listener.
558
576
  *
559
577
  * @remarks
560
578
  * `waitForExit` releases its `exit` listener, and `waitForClose` releases its `close` listener, so
@@ -563,12 +581,20 @@ export declare interface ProcessChild {
563
581
  * @param event - The `exit` or `close` event name
564
582
  * @param listener - The listener registered through `once`
565
583
  * @returns Whatever the emitter returns, which the helpers ignore
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * const settle = (): void => undefined
588
+ * child.once('exit', settle)
589
+ * child.off('exit', settle)
590
+ * ```
566
591
  */
567
592
  off(event: 'exit' | 'close', listener: () => void): unknown;
568
593
  }
569
594
 
570
595
  /**
571
- * A keyed registry of live supervised child processes.
596
+ * Launches supervised children under caller-chosen ids, evicts each one as it settles, and destroys
597
+ * every live child on teardown.
572
598
  *
573
599
  * @remarks
574
600
  * A child launched under an id joins the registry and emits `launch`; when it settles it removes
@@ -599,30 +625,30 @@ export declare interface ProcessChild {
599
625
  export declare class ProcessManager implements ProcessManagerInterface {
600
626
  #private;
601
627
  /**
602
- * Construct a process registry.
628
+ * Constructs a process registry.
603
629
  *
604
630
  * @param options - Initial fleet-level observation hooks and listener-error handling
605
631
  */
606
632
  constructor(options?: ProcessManagerOptions);
607
- /** The typed fleet-level observation surface. */
633
+ /** Holds the typed fleet-level observation surface. */
608
634
  get emitter(): EmitterInterface<ProcessManagerEventMap>;
609
- /** The number of live children. */
635
+ /** Counts the live children. */
610
636
  get count(): number;
611
637
  /**
612
- * The live child under `id`, or `undefined` when none is.
638
+ * Returns the live child under `id`, or `undefined` when none is.
613
639
  *
614
640
  * @param id - The registry key
615
641
  * @returns The child, or `undefined`
616
642
  */
617
643
  process(id: string): ProcessInterface | undefined;
618
644
  /**
619
- * A snapshot of every live child.
645
+ * Returns a snapshot of every live child.
620
646
  *
621
647
  * @returns The live children in launch order
622
648
  */
623
649
  processes(): readonly ProcessInterface[];
624
650
  /**
625
- * Spawn and register one child under `id`.
651
+ * Spawns and registers one child under `id`.
626
652
  *
627
653
  * @remarks
628
654
  * {@link Process} reads every option before it spawns, so a caller's own option getter runs while
@@ -640,27 +666,27 @@ export declare class ProcessManager implements ProcessManagerInterface {
640
666
  */
641
667
  launch(id: string, options: ProcessOptions): ProcessInterface;
642
668
  /**
643
- * Terminate the named children and await their exit.
669
+ * Terminates the named children and awaits their exit.
644
670
  *
645
671
  * @param ids - The registry keys to stop
646
- * @returns True when every named child was live and its exit was confirmed; false otherwise
672
+ * @returns True if every named child was live and its exit was confirmed; false otherwise
647
673
  */
648
674
  stop(ids: readonly string[]): Promise<boolean>;
649
675
  /**
650
- * Terminate one child and await its exit.
676
+ * Terminates one child and awaits its exit.
651
677
  *
652
678
  * @param id - The registry key to stop
653
- * @returns True when the child was live and its exit was confirmed; false when the id was not live or the confirmation deadline elapsed
679
+ * @returns True if the child was live and its exit was confirmed; false otherwise (the id was not live, or the confirmation deadline elapsed)
654
680
  */
655
681
  stop(id: string): Promise<boolean>;
656
682
  /**
657
- * Terminate every live child and await their exit.
683
+ * Terminates every live child and awaits their exit.
658
684
  *
659
685
  * @returns A promise that resolves after every child stops
660
686
  */
661
687
  stop(): Promise<void>;
662
688
  /**
663
- * Stop every child, then destroy the registry emitter last.
689
+ * Stops every child, then destroys the registry emitter last.
664
690
  *
665
691
  * @remarks
666
692
  * Always resolves, and refuses a later `launch` with a {@link createProtocolError}. Each child is
@@ -726,7 +752,8 @@ export declare function readPlatformVariable(environment: Readonly<Record<string
726
752
  export declare function readVariable(environment: Readonly<Record<string, string | undefined>>, name: string): string | undefined;
727
753
 
728
754
  /**
729
- * Resolves a command file to the executable path the host would launch.
755
+ * Resolves a command file to the executable path the host would launch, or to `undefined` on a POSIX
756
+ * host, which performs its own lookup.
730
757
  *
731
758
  * @param file - The command executable name or path
732
759
  * @param options - The directory searched first and the child's effective environment
@@ -773,29 +800,29 @@ export declare function resolveExecutable(file: string, options?: ExecutableOpti
773
800
  export declare class Session implements SessionInterface {
774
801
  #private;
775
802
  /**
776
- * Spawn one child process and begin byte capture.
803
+ * Spawns one child process and begins byte capture.
777
804
  *
778
805
  * @param options - Command, workspace, termination, evidence, stdin, and observation settings
779
806
  * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
780
807
  */
781
808
  constructor(options: SessionOptions);
782
- /** The host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
809
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
783
810
  get pid(): number | undefined;
784
- /** The exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
811
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
785
812
  get code(): number | null;
786
- /** The terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
813
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
787
814
  get signal(): string | null;
788
- /** The typed lifecycle observation surface. */
815
+ /** Holds the typed lifecycle observation surface. */
789
816
  get emitter(): EmitterInterface<SessionEventMap>;
790
- /** The decoded byte-bounded stderr tail, frozen at the terminal moment. */
817
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
791
818
  get evidence(): string;
792
- /** True after the terminal moment arrived and `exit` settled. */
819
+ /** Reports whether the terminal moment arrived and `exit` settled. */
793
820
  get settled(): boolean;
794
- /** True after termination began, including after the terminal moment. `end` never turns it true. */
821
+ /** Reports whether termination began, including after the terminal moment. `end` never turns it true. */
795
822
  get stopping(): boolean;
796
- /** The child's own ending, awaited without the terminal moment's drain window. */
823
+ /** Settles at the child's own ending, awaited without the terminal moment's drain window. */
797
824
  get ending(): Promise<void>;
798
- /** The terminal child state, observed once after stream close or the drain cutoff. */
825
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
799
826
  get exit(): Promise<ProcessExit>;
800
827
  /**
801
828
  * Writes raw bytes to the open standard-input channel.
@@ -807,7 +834,7 @@ export declare class Session implements SessionInterface {
807
834
  * returned promise settles.
808
835
  *
809
836
  * @param bytes - The payload to write, already framed by the caller
810
- * @returns True when the host accepted the bytes without reporting a fault; false when the channel was closed, destroyed, ended, failed, or remained unconfirmed through `delivery`
837
+ * @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
811
838
  */
812
839
  write(bytes: Uint8Array): Promise<boolean>;
813
840
  /**
@@ -827,7 +854,7 @@ export declare class Session implements SessionInterface {
827
854
  * @remarks
828
855
  * Never rejects, and every call shares one termination bounded by `grace` and `drain`.
829
856
  *
830
- * @returns True when the child's native exit was observed; false when the confirmation deadline elapsed without it
857
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
831
858
  */
832
859
  stop(): Promise<boolean>;
833
860
  /**
@@ -880,14 +907,210 @@ export declare function snapshotCommand(command: ProcessCommand): ProcessCommand
880
907
  * @param child - The child boundary
881
908
  * @param grace - The cooperative POSIX window in milliseconds between `SIGTERM` and `SIGKILL`
882
909
  * @param confirm - The milliseconds the native exit is awaited after the final kill
883
- * @returns True when the native exit was observed; false when `confirm` elapsed without it
910
+ * @returns True if the native exit was observed; false otherwise (`confirm` elapsed without it)
884
911
  *
885
912
  * @example
886
913
  * ```ts
887
914
  * const confirmed = await stopChild(child, 5_000, 5_000)
888
915
  * ```
889
916
  */
890
- export declare function stopChild(child: ProcessChild, grace: number, confirm: number): Promise<boolean>;
917
+ export declare function stopChild(child: ProcessChildInterface, grace: number, confirm: number): Promise<boolean>;
918
+
919
+ /**
920
+ * Supervises one child process and reports each lifecycle moment to the face composing it.
921
+ *
922
+ * @remarks
923
+ * This is the engine every supervised-child face shares. It owns the eager spawn, the byte-bounded
924
+ * stderr tail and its decoded chunks, the standard-input channel and its bounded confirmation, the
925
+ * termination sequence, and the progression from the child's native exit through the bounded `drain`
926
+ * window to one terminal moment. It owns no output framing and no observation surface: a face
927
+ * attaches its own consumer to `stdout`, frames bytes however its contract promises, and owns the
928
+ * emitter and event map its consumers subscribe to.
929
+ *
930
+ * The child's ending and the supervision's ending are distinct. `pid`, `code`, and `signal` read the
931
+ * host child directly, so they expose native exit as soon as the host records it, and `ending`
932
+ * settles at that same moment. `settled`, `exit`, and `evidence` reach one terminal moment after the
933
+ * read channels close or the bounded `drain` window cuts them off. That window is armed by the
934
+ * child's native exit and by a termination this package initiated, so every way a child can end
935
+ * reaches the moment. The terminal routine hands the face its `close` and `terminal` moments before
936
+ * it destroys stdout and stderr, so a face's own pull surfaces are final while its read ends still
937
+ * exist.
938
+ *
939
+ * The face is a set of callbacks rather than an emitter, because each face publishes a different
940
+ * event map over the same moments. `chunk` and `fault` carry the live stderr text and the child or
941
+ * channel faults, `relieve` reports that a termination began so the face can release whatever
942
+ * backpressure it holds, `close` ends the face's read pipeline at the terminal moment, `terminal`
943
+ * carries the frozen {@link ProcessExit}, and `teardown` releases the face's own surface after the
944
+ * termination completes. `relieve` is optional because a face that never pauses the child's output
945
+ * holds no backpressure to release, and a face with nothing to do there would otherwise declare an
946
+ * empty method to say so.
947
+ *
948
+ * @example
949
+ * ```ts
950
+ * import { Supervisor } from '@orkestrel/process/server'
951
+ *
952
+ * const engine = new Supervisor(
953
+ * { command: { file: 'node', arguments: ['--version'] }, workspace: process.cwd() },
954
+ * {
955
+ * chunk: () => undefined,
956
+ * fault: () => undefined,
957
+ * close: () => undefined,
958
+ * terminal: () => undefined,
959
+ * teardown: () => undefined,
960
+ * },
961
+ * )
962
+ * const exit = await engine.exit
963
+ * exit.code // 0
964
+ * await engine.destroy()
965
+ * ```
966
+ */
967
+ export declare class Supervisor {
968
+ #private;
969
+ /**
970
+ * Spawns one child process and begins standard-error capture.
971
+ *
972
+ * @remarks
973
+ * The face's callbacks are captured before anything is read or spawned, so the first moment the
974
+ * child can produce already has somewhere to go. `options` supplies the command, workspace,
975
+ * termination, capture, and standard-input settings; a face's own settings, such as an output
976
+ * retention bound, are read and validated by that face before it constructs this engine, so an
977
+ * invalid one refuses construction while nothing has been spawned.
978
+ *
979
+ * @param options - Command, workspace, termination, capture, and stdin settings
980
+ * @param face - The composing face's callbacks for each lifecycle moment
981
+ * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
982
+ */
983
+ constructor(options: ProcessOptions, face: SupervisorFace);
984
+ /** Holds the child's standard-output stream, for the composing face to attach its own consumer to. */
985
+ get stdout(): Readable;
986
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
987
+ get pid(): number | undefined;
988
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
989
+ get code(): number | null;
990
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
991
+ get signal(): string | null;
992
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
993
+ get evidence(): string;
994
+ /** Reports whether the terminal moment arrived and `exit` settled. */
995
+ get settled(): boolean;
996
+ /** Reports whether termination began, including after the terminal moment. */
997
+ get stopping(): boolean;
998
+ /**
999
+ * Settles at the child's own ending, awaited without the terminal moment's drain window.
1000
+ *
1001
+ * @remarks
1002
+ * Never rejects, and resolves no value: `code` and `signal` carry the terminal facts as soon as
1003
+ * the host records them. It settles at the native exit, and at the terminal moment for a child
1004
+ * whose spawn produced no native exit at all, so it can never outlive the supervision.
1005
+ */
1006
+ get ending(): Promise<void>;
1007
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
1008
+ get exit(): Promise<ProcessExit>;
1009
+ /**
1010
+ * Writes raw bytes to the open standard-input channel.
1011
+ *
1012
+ * @remarks
1013
+ * Never rejects, and adds no framing: a face composes whatever terminator its contract promises
1014
+ * before it calls this. `true` means the host accepted the bytes without reporting a fault; it
1015
+ * does not prove that the child read them. An ordinary write settles when the kernel accepts it.
1016
+ * Only a full pipe can hold the write unconfirmed. The `delivery` option can bound that wait, and
1017
+ * every terminal teardown path settles pending writes. After `stop` or `destroy` begins, a later
1018
+ * call settles `false`, because teardown cannot confirm delivery for bytes it is about to
1019
+ * discard.
1020
+ *
1021
+ * @param bytes - The payload to write, already framed by the caller
1022
+ * @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
1023
+ *
1024
+ * @example
1025
+ * ```ts
1026
+ * import { Supervisor } from '@orkestrel/process/server'
1027
+ *
1028
+ * const engine = new Supervisor(
1029
+ * {
1030
+ * command: { file: 'node', arguments: ['-e', 'process.stdin.pipe(process.stdout)'] },
1031
+ * workspace: process.cwd(),
1032
+ * writable: true,
1033
+ * },
1034
+ * {
1035
+ * chunk: () => undefined,
1036
+ * fault: () => undefined,
1037
+ * close: () => undefined,
1038
+ * terminal: () => undefined,
1039
+ * teardown: () => undefined,
1040
+ * },
1041
+ * )
1042
+ * const accepted = await engine.deliver(new TextEncoder().encode('ping\n'))
1043
+ * accepted // true
1044
+ * await engine.destroy()
1045
+ * ```
1046
+ */
1047
+ deliver(bytes: Uint8Array): Promise<boolean>;
1048
+ /**
1049
+ * Closes the standard-input channel while leaving the child running.
1050
+ *
1051
+ * @remarks
1052
+ * Never rejects, and terminates nothing: no signal is sent, `stopping` stays false, no drain
1053
+ * window is armed, and the terminal moment does not arrive. The child observes end of input and
1054
+ * decides for itself what to do about it, which is what separates this from `stop`.
1055
+ *
1056
+ * Every call shares one barrier, and it resolves after the host flushes the writes it had already
1057
+ * accepted, or reports that it cannot. A `deliver` after this call resolves `false`, because the
1058
+ * host stops reporting the channel writable the moment it is ended. That same flag keeps the
1059
+ * ended channel quiet for its remaining life, so a later host fault on it settles pending writes
1060
+ * and reaches no face. After `stop` or `destroy` has begun, or after the terminal moment, the
1061
+ * call resolves and changes nothing, because the channel is already being discarded.
1062
+ *
1063
+ * @returns The stable barrier shared by every call
1064
+ */
1065
+ end(): Promise<void>;
1066
+ /**
1067
+ * Terminates the child process tree and reaches the terminal observation moment.
1068
+ *
1069
+ * @remarks
1070
+ * Never rejects, and every call shares one termination. After the termination sequence returns,
1071
+ * confirmed or not, it waits at most `drain` for the read channels to close, then cuts them off
1072
+ * and settles `exit` when they remain open. A cutoff reached before the native exit reports the
1073
+ * `code` and `signal` the host had recorded by then, which is `null` for a child still running.
1074
+ *
1075
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
1076
+ */
1077
+ stop(): Promise<boolean>;
1078
+ /**
1079
+ * Stops the child and releases the composing face after the terminal state freezes.
1080
+ *
1081
+ * @remarks
1082
+ * Always resolves, including when termination was never confirmed. Every call shares one barrier.
1083
+ *
1084
+ * @returns The stable barrier shared by every call
1085
+ */
1086
+ destroy(): Promise<void>;
1087
+ }
1088
+
1089
+ /**
1090
+ * Represents the composing face's callbacks for each lifecycle moment of one supervised child.
1091
+ *
1092
+ * @remarks
1093
+ * `Process` and `Session` each construct one and hand it to the supervision engine, which captures
1094
+ * every callback before anything is read or spawned, so the first moment the child can produce
1095
+ * already has somewhere to go. `chunk` receives each decoded standard-error fragment, `fault` the
1096
+ * host error that ended the run, `close` the moment the read channels closed, `terminal` the frozen
1097
+ * exit state, and `teardown` the release of whatever the face still holds. `relieve` is optional
1098
+ * because a face that never pauses the child's output holds no backpressure to release.
1099
+ */
1100
+ export declare interface SupervisorFace {
1101
+ /** Receives one decoded standard-error fragment. */
1102
+ readonly chunk: (text: string) => void;
1103
+ /** Receives the host error that ended the run. */
1104
+ readonly fault: (cause: unknown) => void;
1105
+ /** Reports that a termination began, so a face holding output backpressure releases it. */
1106
+ readonly relieve?: () => void;
1107
+ /** Reports that the child's read channels closed. */
1108
+ readonly close: () => void;
1109
+ /** Receives the frozen terminal state. */
1110
+ readonly terminal: (exit: ProcessExit) => void;
1111
+ /** Releases whatever the face still holds after the terminal moment. */
1112
+ readonly teardown: () => void;
1113
+ }
891
1114
 
892
1115
  /**
893
1116
  * Trims a buffer to at most `limit` leading bytes without splitting a UTF-8 sequence.
@@ -1036,14 +1259,14 @@ export declare function validateWorkspace(workspace: string | undefined): void;
1036
1259
  *
1037
1260
  * @param child - The child boundary
1038
1261
  * @param timeout - The milliseconds to wait before giving up
1039
- * @returns True when the host close arrived inside the deadline; false otherwise
1262
+ * @returns True if the host close arrived inside the deadline; false otherwise
1040
1263
  *
1041
1264
  * @example
1042
1265
  * ```ts
1043
1266
  * const closed = await waitForClose(child, 5_000)
1044
1267
  * ```
1045
1268
  */
1046
- export declare function waitForClose(child: Pick<ProcessChild, 'once' | 'off'>, timeout: number): Promise<boolean>;
1269
+ export declare function waitForClose(child: Pick<ProcessChildInterface, 'once' | 'off'>, timeout: number): Promise<boolean>;
1047
1270
 
1048
1271
  /**
1049
1272
  * Waits for one child process's native exit, bounded by a deadline.
@@ -1057,6 +1280,6 @@ export declare function waitForClose(child: Pick<ProcessChild, 'once' | 'off'>,
1057
1280
  * await waitForExit(child, 5_000)
1058
1281
  * ```
1059
1282
  */
1060
- export declare function waitForExit(child: Pick<ProcessChild, 'exitCode' | 'signalCode' | 'once' | 'off'>, timeout: number): Promise<void>;
1283
+ export declare function waitForExit(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode' | 'once' | 'off'>, timeout: number): Promise<void>;
1061
1284
 
1062
1285
  export { }