@orkestrel/process 0.0.8 → 0.0.10

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.
@@ -5,20 +5,26 @@ import { ExecutableOptions } from '@orkestrel/process';
5
5
  import { ExecuteInput } from '@orkestrel/process';
6
6
  import { ExecuteOptions } from '@orkestrel/process';
7
7
  import { ExecuteResult } from '@orkestrel/process';
8
- import { ExecuteResult as ExecuteResult_2 } from '@orkestrel/process';
9
8
  import { ExecuteSyncOptions } from '@orkestrel/process';
10
9
  import { ProcessCommand } from '@orkestrel/process';
11
- import { ProcessCommand as ProcessCommand_2 } from '@orkestrel/process';
12
10
  import { ProcessEventMap } from '@orkestrel/process';
13
11
  import { ProcessExit } from '@orkestrel/process';
12
+ import { ProcessExit as ProcessExit_2 } from '@orkestrel/process';
14
13
  import { ProcessInterface } from '@orkestrel/process';
14
+ import { ProcessInterface as ProcessInterface_2 } from '@orkestrel/process';
15
15
  import { ProcessManagerEventMap } from '@orkestrel/process';
16
16
  import { ProcessManagerInterface } from '@orkestrel/process';
17
+ import { ProcessManagerInterface as ProcessManagerInterface_2 } from '@orkestrel/process';
17
18
  import { ProcessManagerOptions } from '@orkestrel/process';
19
+ import { ProcessManagerOptions as ProcessManagerOptions_2 } from '@orkestrel/process';
18
20
  import { ProcessOptions } from '@orkestrel/process';
21
+ import { ProcessOptions as ProcessOptions_2 } from '@orkestrel/process';
22
+ import { Readable } from 'node:stream';
19
23
  import { SessionEventMap } from '@orkestrel/process';
20
24
  import { SessionInterface } from '@orkestrel/process';
25
+ import { SessionInterface as SessionInterface_2 } from '@orkestrel/process';
21
26
  import { SessionOptions } from '@orkestrel/process';
27
+ import { SessionOptions as SessionOptions_2 } from '@orkestrel/process';
22
28
  import { SpawnInput } from '@orkestrel/process';
23
29
 
24
30
  /**
@@ -120,6 +126,30 @@ export declare function buildPlatformSpawn(command: ProcessCommand, file: string
120
126
  */
121
127
  export declare function buildSpawn(command: ProcessCommand, options?: ExecutableOptions): SpawnInput;
122
128
 
129
+ /**
130
+ * Bounds one delivered stream chunk to the bytes a capture still has room for.
131
+ *
132
+ * @remarks
133
+ * A chunk that is not a buffer contributes nothing and reports `undefined` rather than throwing,
134
+ * because a stream `data` listener receives an `unknown` payload. The cut is byte-exact and might
135
+ * land inside a multibyte sequence, because {@link buildExecuteResult} performs the single
136
+ * code-point-boundary trim over the whole capture rather than over each chunk. Give the capture one
137
+ * byte more room than its limit, so that final trim can read the first excluded byte and retreat off
138
+ * a split sequence. A chunk that fits its room is returned as the delivered buffer itself rather
139
+ * than a copy, because a capture appending it copies again and never writes through it; a chunk that
140
+ * overruns its room returns a copy of the bytes that fit. Treat the return as read-only either way.
141
+ *
142
+ * @param chunk - The delivered chunk, ignored when it is not a buffer
143
+ * @param room - The bytes the capture still accepts
144
+ * @returns The bytes to retain, or `undefined` when the chunk contributes none
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * captureChunk(Buffer.from('hello'), 3) // <Buffer 68 65 6c>
149
+ * ```
150
+ */
151
+ export declare function captureChunk(chunk: unknown, room: number): Buffer_2 | undefined;
152
+
123
153
  /**
124
154
  * Creates one supervised child process.
125
155
  *
@@ -192,7 +222,7 @@ export declare function createSession(options: SessionOptions): SessionInterface
192
222
  * detach({ file: 'node', arguments: ['daemon.js'] }, { workspace: process.cwd() })
193
223
  * ```
194
224
  */
195
- export declare function detach(command: ProcessCommand_2, options?: DetachOptions): void;
225
+ export declare function detach(command: ProcessCommand, options?: DetachOptions): void;
196
226
 
197
227
  /**
198
228
  * Runs one command to completion, buffering its output, and settles with the outcome.
@@ -201,7 +231,9 @@ export declare function detach(command: ProcessCommand_2, options?: DetachOption
201
231
  * The executable is resolved through {@link buildSpawn}, so no run uses a shell. On a POSIX host the
202
232
  * child is detached, which is what lets its whole process group be terminated. Standard output and
203
233
  * error are each byte-bounded by `limit` (default {@link PROCESS_OUTPUT}) and `truncated` reports
204
- * whether either stream exceeded it. A positive `timeout` and an aborting `signal` both terminate the
234
+ * whether either stream exceeded it. Each capture keeps one byte beyond `limit`, so the single
235
+ * code-point-boundary trim in {@link buildExecuteResult} reads the first excluded byte and never
236
+ * delivers a split multibyte sequence. A positive `timeout` and an aborting `signal` both terminate the
205
237
  * child through the same bounded stop, and only the earliest is recorded: a timeout reports
206
238
  * `expired` and an abort reports `aborted`, never both. After termination the outcome is awaited for
207
239
  * a bounded window, so a descendant holding the child's stdio cannot keep the run pending. That bound
@@ -227,7 +259,7 @@ export declare function detach(command: ProcessCommand_2, options?: DetachOption
227
259
  * const result = await execute({ file: 'git', arguments: ['status'] }, { workspace: process.cwd() })
228
260
  * ```
229
261
  */
230
- export declare function execute(command: ProcessCommand_2, options?: ExecuteOptions): Promise<ExecuteResult_2>;
262
+ export declare function execute(command: ProcessCommand, options?: ExecuteOptions): Promise<ExecuteResult>;
231
263
 
232
264
  /**
233
265
  * Runs one command to completion synchronously, buffering its output, and returns the outcome.
@@ -253,7 +285,7 @@ export declare function execute(command: ProcessCommand_2, options?: ExecuteOpti
253
285
  * const result = executeSync({ file: 'git', arguments: ['--version'] }, { strict: false })
254
286
  * ```
255
287
  */
256
- export declare function executeSync(command: ProcessCommand_2, options?: ExecuteSyncOptions): ExecuteResult_2;
288
+ export declare function executeSync(command: ProcessCommand, options?: ExecuteSyncOptions): ExecuteResult;
257
289
 
258
290
  /**
259
291
  * Renders one command into its diagnostic command line.
@@ -277,14 +309,14 @@ export declare function formatCommand(command: ProcessCommand): string;
277
309
  * initiated against a pid the host may have reused.
278
310
  *
279
311
  * @param child - The child boundary
280
- * @returns True when the process has exited; false while it is live
312
+ * @returns True if the process has exited; false otherwise
281
313
  *
282
314
  * @example
283
315
  * ```ts
284
316
  * isExited({ exitCode: 0, signalCode: null }) // true
285
317
  * ```
286
318
  */
287
- export declare function isExited(child: Pick<ProcessChild, 'exitCode' | 'signalCode'>): boolean;
319
+ export declare function isExited(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode'>): boolean;
288
320
 
289
321
  /**
290
322
  * Checks whether a path names a regular file.
@@ -294,7 +326,7 @@ export declare function isExited(child: Pick<ProcessChild, 'exitCode' | 'signalC
294
326
  * command. An unreadable or malformed path reports `false` rather than throwing.
295
327
  *
296
328
  * @param target - The absolute or relative path to inspect
297
- * @returns True when the path resolves to a regular file; false otherwise
329
+ * @returns True if the path resolves to a regular file; false otherwise
298
330
  *
299
331
  * @example
300
332
  * ```ts
@@ -323,7 +355,7 @@ export declare function isFile(target: string): boolean;
323
355
  * killProcess(child, 'SIGTERM')
324
356
  * ```
325
357
  */
326
- export declare function killProcess(child: Pick<ProcessChild, 'pid' | 'kill'>, signal: NodeJS.Signals): void;
358
+ export declare function killProcess(child: Pick<ProcessChildInterface, 'pid' | 'kill'>, signal: NodeJS.Signals): void;
327
359
 
328
360
  /**
329
361
  * Kills one Windows process tree through `taskkill`.
@@ -337,7 +369,7 @@ export declare function killProcess(child: Pick<ProcessChild, 'pid' | 'kill'>, s
337
369
  *
338
370
  * @param pid - The root process id of the tree to end
339
371
  * @param timeout - The milliseconds the utility is given before it is killed
340
- * @returns True when the utility reported success; false when it failed, was unavailable, or was cut off
372
+ * @returns True if the utility reported success; false otherwise (it failed, was unavailable, or was cut off)
341
373
  *
342
374
  * @example
343
375
  * ```ts
@@ -414,37 +446,37 @@ export declare function mergePlatformEnvironment(platform: NodeJS.Platform, pare
414
446
  * await child.destroy()
415
447
  * ```
416
448
  */
417
- export declare class Process implements ProcessInterface {
449
+ export declare class Process implements ProcessInterface_2 {
418
450
  #private;
419
451
  /**
420
- * Spawn one child process and begin stream capture.
452
+ * Spawns one child process and begins stream capture.
421
453
  *
422
454
  * @param options - Command, workspace, termination, capture, stdin, and observation settings
423
455
  * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
424
456
  */
425
- constructor(options: ProcessOptions);
426
- /** The host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
457
+ constructor(options: ProcessOptions_2);
458
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
427
459
  get pid(): number | undefined;
428
- /** The exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
460
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
429
461
  get code(): number | null;
430
- /** The terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
462
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
431
463
  get signal(): string | null;
432
- /** The typed lifecycle observation surface. */
464
+ /** Holds the typed lifecycle observation surface. */
433
465
  get emitter(): EmitterInterface<ProcessEventMap>;
434
- /** The captured stdout lines, in arrival order, ending after queued lines at the terminal moment. */
466
+ /** Yields the captured stdout lines, in arrival order, ending after queued lines at the terminal moment. */
435
467
  get lines(): AsyncIterable<string>;
436
- /** The decoded byte-bounded stderr tail, frozen at the terminal moment. */
468
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
437
469
  get evidence(): string;
438
- /** True when the `lines` stream omitted output after a retention bound was reached. */
470
+ /** Reports whether the `lines` stream omitted output after a retention bound was reached. */
439
471
  get truncated(): boolean;
440
- /** True after the terminal moment arrived and `exit` settled. */
472
+ /** Reports whether the terminal moment arrived and `exit` settled. */
441
473
  get settled(): boolean;
442
- /** True after termination began, including after the terminal moment. */
474
+ /** Reports whether termination began, including after the terminal moment. */
443
475
  get stopping(): boolean;
444
- /** The terminal child state, observed once after stream close or the drain cutoff. */
445
- get exit(): Promise<ProcessExit>;
476
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
477
+ get exit(): Promise<ProcessExit_2>;
446
478
  /**
447
- * Write one line to the open standard-input channel.
479
+ * Writes one line to the open standard-input channel.
448
480
  *
449
481
  * @remarks
450
482
  * Never rejects. `true` means the host accepted the bytes without reporting a fault; it does not
@@ -458,7 +490,7 @@ export declare class Process implements ProcessInterface {
458
490
  * for bytes the package is about to discard.
459
491
  *
460
492
  * @param text - The line text without its trailing newline
461
- * @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`
493
+ * @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`)
462
494
  */
463
495
  send(text: string): Promise<boolean>;
464
496
  /**
@@ -470,7 +502,7 @@ export declare class Process implements ProcessInterface {
470
502
  * and settles `exit` when they remain open. A cutoff reached before the native exit reports the
471
503
  * `code` and `signal` the host had recorded by then, which is `null` for a child still running.
472
504
  *
473
- * @returns True when the child's native exit was observed; false when the confirmation deadline elapsed without it
505
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
474
506
  */
475
507
  stop(): Promise<boolean>;
476
508
  /**
@@ -485,15 +517,7 @@ export declare class Process implements ProcessInterface {
485
517
  }
486
518
 
487
519
  /**
488
- * The Node-side contracts of `@orkestrel/process/server`.
489
- *
490
- * @remarks
491
- * The host-independent contracts live in `@orkestrel/process`. This module declares only what a
492
- * Node child process boundary requires, which the published contracts cannot express without
493
- * naming `node:child_process` types.
494
- */
495
- /**
496
- * The child boundary the termination helpers drive.
520
+ * Represents the child boundary the termination helpers drive.
497
521
  *
498
522
  * @remarks
499
523
  * A `ChildProcess` satisfies this structurally, and so does any object carrying the same
@@ -507,30 +531,42 @@ export declare class Process implements ProcessInterface {
507
531
  * the route that reaches it: `killProcess` signals the negated `pid` first and falls back to `kill`
508
532
  * when the host reports that no group owns that pid.
509
533
  */
510
- export declare interface ProcessChild {
511
- /** The process id the host assigned, or `undefined` when the spawn never produced one. */
534
+ export declare interface ProcessChildInterface {
535
+ /** Holds the process id the host assigned, or `undefined` when the spawn never produced one. */
512
536
  readonly pid?: number | undefined;
513
- /** The exit code, or `null` while the process is live or a signal ended it. */
537
+ /** Holds the exit code, or `null` while the process is live or a signal ended it. */
514
538
  readonly exitCode: number | null;
515
- /** The terminating signal name, or `null` while the process is live or it exited on its own. */
539
+ /** Holds the terminating signal name, or `null` while the process is live or it exited on its own. */
516
540
  readonly signalCode: string | null;
517
541
  /**
518
- * Deliver one signal to the process.
542
+ * Delivers one signal to the process.
519
543
  *
520
544
  * @param signal - The signal to deliver
521
- * @returns True when the host accepted the signal; false otherwise
545
+ * @returns True if the host accepted the signal; false otherwise
546
+ *
547
+ * @example
548
+ * ```ts
549
+ * const accepted = child.kill('SIGTERM')
550
+ * accepted // true
551
+ * ```
522
552
  */
523
553
  kill(signal: NodeJS.Signals): boolean;
524
554
  /**
525
- * Register a one-shot listener for the native exit or stream close.
555
+ * Registers a one-shot listener for the native exit or stream close.
526
556
  *
527
557
  * @param event - The `exit` or `close` event name
528
558
  * @param listener - The listener invoked after the selected event
529
559
  * @returns Whatever the emitter returns, which the helpers ignore
560
+ *
561
+ * @example
562
+ * ```ts
563
+ * const settle = (): void => undefined
564
+ * child.once('exit', settle)
565
+ * ```
530
566
  */
531
567
  once(event: 'exit' | 'close', listener: () => void): unknown;
532
568
  /**
533
- * Release one previously registered exit or close listener.
569
+ * Releases one previously registered exit or close listener.
534
570
  *
535
571
  * @remarks
536
572
  * `waitForExit` releases its `exit` listener, and `waitForClose` releases its `close` listener, so
@@ -539,12 +575,19 @@ export declare interface ProcessChild {
539
575
  * @param event - The `exit` or `close` event name
540
576
  * @param listener - The listener registered through `once`
541
577
  * @returns Whatever the emitter returns, which the helpers ignore
578
+ *
579
+ * @example
580
+ * ```ts
581
+ * const settle = (): void => undefined
582
+ * child.once('exit', settle)
583
+ * child.off('exit', settle)
584
+ * ```
542
585
  */
543
586
  off(event: 'exit' | 'close', listener: () => void): unknown;
544
587
  }
545
588
 
546
589
  /**
547
- * A keyed registry of live supervised child processes.
590
+ * Represents a keyed registry of live supervised child processes.
548
591
  *
549
592
  * @remarks
550
593
  * A child launched under an id joins the registry and emits `launch`; when it settles it removes
@@ -572,33 +615,33 @@ export declare interface ProcessChild {
572
615
  * await manager.destroy()
573
616
  * ```
574
617
  */
575
- export declare class ProcessManager implements ProcessManagerInterface {
618
+ export declare class ProcessManager implements ProcessManagerInterface_2 {
576
619
  #private;
577
620
  /**
578
- * Construct a process registry.
621
+ * Constructs a process registry.
579
622
  *
580
623
  * @param options - Initial fleet-level observation hooks and listener-error handling
581
624
  */
582
- constructor(options?: ProcessManagerOptions);
583
- /** The typed fleet-level observation surface. */
625
+ constructor(options?: ProcessManagerOptions_2);
626
+ /** Holds the typed fleet-level observation surface. */
584
627
  get emitter(): EmitterInterface<ProcessManagerEventMap>;
585
- /** The number of live children. */
628
+ /** Counts the live children. */
586
629
  get count(): number;
587
630
  /**
588
- * The live child under `id`, or `undefined` when none is.
631
+ * Returns the live child under `id`, or `undefined` when none is.
589
632
  *
590
633
  * @param id - The registry key
591
634
  * @returns The child, or `undefined`
592
635
  */
593
- process(id: string): ProcessInterface | undefined;
636
+ process(id: string): ProcessInterface_2 | undefined;
594
637
  /**
595
- * A snapshot of every live child.
638
+ * Returns a snapshot of every live child.
596
639
  *
597
640
  * @returns The live children in launch order
598
641
  */
599
- processes(): readonly ProcessInterface[];
642
+ processes(): readonly ProcessInterface_2[];
600
643
  /**
601
- * Spawn and register one child under `id`.
644
+ * Spawns and registers one child under `id`.
602
645
  *
603
646
  * @remarks
604
647
  * {@link Process} reads every option before it spawns, so a caller's own option getter runs while
@@ -614,29 +657,29 @@ export declare class ProcessManager implements ProcessManagerInterface {
614
657
  * @returns The launched child
615
658
  * @throws A {@link ProcessError} coded `duplicate` when `id` is already live, `protocol` when the registry is being destroyed, or `invalid` when an option or command string is malformed
616
659
  */
617
- launch(id: string, options: ProcessOptions): ProcessInterface;
660
+ launch(id: string, options: ProcessOptions_2): ProcessInterface_2;
618
661
  /**
619
- * Terminate the named children and await their exit.
662
+ * Terminates the named children and awaits their exit.
620
663
  *
621
664
  * @param ids - The registry keys to stop
622
- * @returns True when every named child was live and its exit was confirmed; false otherwise
665
+ * @returns True if every named child was live and its exit was confirmed; false otherwise
623
666
  */
624
667
  stop(ids: readonly string[]): Promise<boolean>;
625
668
  /**
626
- * Terminate one child and await its exit.
669
+ * Terminates one child and awaits its exit.
627
670
  *
628
671
  * @param id - The registry key to stop
629
- * @returns True when the child was live and its exit was confirmed; false when the id was not live or the confirmation deadline elapsed
672
+ * @returns True if the child was live and its exit was confirmed; false otherwise (the id was not live, or the confirmation deadline elapsed)
630
673
  */
631
674
  stop(id: string): Promise<boolean>;
632
675
  /**
633
- * Terminate every live child and await their exit.
676
+ * Terminates every live child and awaits their exit.
634
677
  *
635
678
  * @returns A promise that resolves after every child stops
636
679
  */
637
680
  stop(): Promise<void>;
638
681
  /**
639
- * Stop every child, then destroy the registry emitter last.
682
+ * Stops every child, then destroys the registry emitter last.
640
683
  *
641
684
  * @remarks
642
685
  * Always resolves, and refuses a later `launch` with a {@link createProtocolError}. Each child is
@@ -715,48 +758,6 @@ export declare function readVariable(environment: Readonly<Record<string, string
715
758
  */
716
759
  export declare function resolveExecutable(file: string, options?: ExecutableOptions): string | undefined;
717
760
 
718
- /**
719
- * Accumulates byte totals while retaining a bounded stream head.
720
- *
721
- * @example
722
- * ```ts
723
- * const retention = new Retention()
724
- * retention.retain(Buffer.from('hello'), 3)?.toString('utf8') // 'hel'
725
- * retention.retained // 3
726
- * ```
727
- */
728
- export declare class Retention implements RetentionInterface {
729
- #private;
730
- /** The bytes delivered by the stream. */
731
- get delivered(): number;
732
- /** The bytes retained from the stream head. */
733
- get retained(): number;
734
- /**
735
- * Retains a delivered chunk within a byte limit.
736
- *
737
- * @param chunk - The delivered chunk, ignored when it is not a buffer
738
- * @param limit - The maximum retained byte count
739
- * @returns The retained slice, or `undefined` when the chunk contributes no retained bytes
740
- */
741
- retain(chunk: unknown, limit: number): Buffer_2 | undefined;
742
- }
743
-
744
- /** Exposes byte totals and bounded stream-head retention. */
745
- export declare interface RetentionInterface {
746
- /** The bytes delivered by the stream. */
747
- readonly delivered: number;
748
- /** The bytes retained from the stream head. */
749
- readonly retained: number;
750
- /**
751
- * Retains a delivered chunk within a byte limit.
752
- *
753
- * @param chunk - The delivered chunk, ignored when it is not a buffer
754
- * @param limit - The maximum retained byte count
755
- * @returns The retained slice, or `undefined` when the chunk contributes no retained bytes
756
- */
757
- retain(chunk: unknown, limit: number): Buffer_2 | undefined;
758
- }
759
-
760
761
  /**
761
762
  * Supervises one child and publishes its standard output as raw bytes.
762
763
  *
@@ -788,33 +789,33 @@ export declare interface RetentionInterface {
788
789
  * })
789
790
  * ```
790
791
  */
791
- export declare class Session implements SessionInterface {
792
+ export declare class Session implements SessionInterface_2 {
792
793
  #private;
793
794
  /**
794
- * Spawn one child process and begin byte capture.
795
+ * Spawns one child process and begins byte capture.
795
796
  *
796
797
  * @param options - Command, workspace, termination, evidence, stdin, and observation settings
797
798
  * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
798
799
  */
799
- constructor(options: SessionOptions);
800
- /** The host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
800
+ constructor(options: SessionOptions_2);
801
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
801
802
  get pid(): number | undefined;
802
- /** The exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
803
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
803
804
  get code(): number | null;
804
- /** The terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
805
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
805
806
  get signal(): string | null;
806
- /** The typed lifecycle observation surface. */
807
+ /** Holds the typed lifecycle observation surface. */
807
808
  get emitter(): EmitterInterface<SessionEventMap>;
808
- /** The decoded byte-bounded stderr tail, frozen at the terminal moment. */
809
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
809
810
  get evidence(): string;
810
- /** True after the terminal moment arrived and `exit` settled. */
811
+ /** Reports whether the terminal moment arrived and `exit` settled. */
811
812
  get settled(): boolean;
812
- /** True after termination began, including after the terminal moment. `end` never turns it true. */
813
+ /** Reports whether termination began, including after the terminal moment. `end` never turns it true. */
813
814
  get stopping(): boolean;
814
- /** The child's own ending, awaited without the terminal moment's drain window. */
815
+ /** Settles at the child's own ending, awaited without the terminal moment's drain window. */
815
816
  get ending(): Promise<void>;
816
- /** The terminal child state, observed once after stream close or the drain cutoff. */
817
- get exit(): Promise<ProcessExit>;
817
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
818
+ get exit(): Promise<ProcessExit_2>;
818
819
  /**
819
820
  * Writes raw bytes to the open standard-input channel.
820
821
  *
@@ -825,7 +826,7 @@ export declare class Session implements SessionInterface {
825
826
  * returned promise settles.
826
827
  *
827
828
  * @param bytes - The payload to write, already framed by the caller
828
- * @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`
829
+ * @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`)
829
830
  */
830
831
  write(bytes: Uint8Array): Promise<boolean>;
831
832
  /**
@@ -845,7 +846,7 @@ export declare class Session implements SessionInterface {
845
846
  * @remarks
846
847
  * Never rejects, and every call shares one termination bounded by `grace` and `drain`.
847
848
  *
848
- * @returns True when the child's native exit was observed; false when the confirmation deadline elapsed without it
849
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
849
850
  */
850
851
  stop(): Promise<boolean>;
851
852
  /**
@@ -898,22 +899,221 @@ export declare function snapshotCommand(command: ProcessCommand): ProcessCommand
898
899
  * @param child - The child boundary
899
900
  * @param grace - The cooperative POSIX window in milliseconds between `SIGTERM` and `SIGKILL`
900
901
  * @param confirm - The milliseconds the native exit is awaited after the final kill
901
- * @returns True when the native exit was observed; false when `confirm` elapsed without it
902
+ * @returns True if the native exit was observed; false otherwise (`confirm` elapsed without it)
902
903
  *
903
904
  * @example
904
905
  * ```ts
905
906
  * const confirmed = await stopChild(child, 5_000, 5_000)
906
907
  * ```
907
908
  */
908
- export declare function stopChild(child: ProcessChild, grace: number, confirm: number): Promise<boolean>;
909
+ export declare function stopChild(child: ProcessChildInterface, grace: number, confirm: number): Promise<boolean>;
910
+
911
+ /**
912
+ * Supervises one child process and reports each lifecycle moment to the face composing it.
913
+ *
914
+ * @remarks
915
+ * This is the engine every supervised-child face shares. It owns the eager spawn, the byte-bounded
916
+ * stderr tail and its decoded chunks, the standard-input channel and its bounded confirmation, the
917
+ * termination sequence, and the progression from the child's native exit through the bounded `drain`
918
+ * window to one terminal moment. It owns no output framing and no observation surface: a face
919
+ * attaches its own consumer to `stdout`, frames bytes however its contract promises, and owns the
920
+ * emitter and event map its consumers subscribe to.
921
+ *
922
+ * The child's ending and the supervision's ending are distinct. `pid`, `code`, and `signal` read the
923
+ * host child directly, so they expose native exit as soon as the host records it, and `ending`
924
+ * settles at that same moment. `settled`, `exit`, and `evidence` reach one terminal moment after the
925
+ * read channels close or the bounded `drain` window cuts them off. That window is armed by the
926
+ * child's native exit and by a termination this package initiated, so every way a child can end
927
+ * reaches the moment. The terminal routine hands the face its `close` and `terminal` moments before
928
+ * it destroys stdout and stderr, so a face's own pull surfaces are final while its read ends still
929
+ * exist.
930
+ *
931
+ * The face is a set of callbacks rather than an emitter, because each face publishes a different
932
+ * event map over the same moments. `chunk` and `fault` carry the live stderr text and the child or
933
+ * channel faults, `relieve` reports that a termination began so the face can release whatever
934
+ * backpressure it holds, `close` ends the face's read pipeline at the terminal moment, `terminal`
935
+ * carries the frozen {@link ProcessExit}, and `teardown` releases the face's own surface after the
936
+ * termination completes. `relieve` is optional because a face that never pauses the child's output
937
+ * holds no backpressure to release, and a face with nothing to do there would otherwise declare an
938
+ * empty method to say so.
939
+ *
940
+ * @example
941
+ * ```ts
942
+ * import { Supervisor } from '@orkestrel/process/server'
943
+ *
944
+ * const engine = new Supervisor(
945
+ * { command: { file: 'node', arguments: ['--version'] }, workspace: process.cwd() },
946
+ * {
947
+ * chunk: () => undefined,
948
+ * fault: () => undefined,
949
+ * close: () => undefined,
950
+ * terminal: () => undefined,
951
+ * teardown: () => undefined,
952
+ * },
953
+ * )
954
+ * const exit = await engine.exit
955
+ * exit.code // 0
956
+ * await engine.destroy()
957
+ * ```
958
+ */
959
+ export declare class Supervisor {
960
+ #private;
961
+ /**
962
+ * Spawns one child process and begins standard-error capture.
963
+ *
964
+ * @remarks
965
+ * The face's callbacks are captured before anything is read or spawned, so the first moment the
966
+ * child can produce already has somewhere to go. `options` supplies the command, workspace,
967
+ * termination, capture, and standard-input settings; a face's own settings, such as an output
968
+ * retention bound, are read and validated by that face before it constructs this engine, so an
969
+ * invalid one refuses construction while nothing has been spawned.
970
+ *
971
+ * @param options - Command, workspace, termination, capture, and stdin settings
972
+ * @param face - The composing face's callbacks for each lifecycle moment
973
+ * @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
974
+ */
975
+ constructor(options: ProcessOptions_2, face: SupervisorFace);
976
+ /** Holds the child's standard-output stream, for the composing face to attach its own consumer to. */
977
+ get stdout(): Readable;
978
+ /** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
979
+ get pid(): number | undefined;
980
+ /** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
981
+ get code(): number | null;
982
+ /** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
983
+ get signal(): string | null;
984
+ /** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
985
+ get evidence(): string;
986
+ /** Reports whether the terminal moment arrived and `exit` settled. */
987
+ get settled(): boolean;
988
+ /** Reports whether termination began, including after the terminal moment. */
989
+ get stopping(): boolean;
990
+ /**
991
+ * Settles at the child's own ending, awaited without the terminal moment's drain window.
992
+ *
993
+ * @remarks
994
+ * Never rejects, and resolves no value: `code` and `signal` carry the terminal facts as soon as
995
+ * the host records them. It settles at the native exit, and at the terminal moment for a child
996
+ * whose spawn produced no native exit at all, so it can never outlive the supervision.
997
+ */
998
+ get ending(): Promise<void>;
999
+ /** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
1000
+ get exit(): Promise<ProcessExit_2>;
1001
+ /**
1002
+ * Writes raw bytes to the open standard-input channel.
1003
+ *
1004
+ * @remarks
1005
+ * Never rejects, and adds no framing: a face composes whatever terminator its contract promises
1006
+ * before it calls this. `true` means the host accepted the bytes without reporting a fault; it
1007
+ * does not prove that the child read them. An ordinary write settles when the kernel accepts it.
1008
+ * Only a full pipe can hold the write unconfirmed. The `delivery` option can bound that wait, and
1009
+ * every terminal teardown path settles pending writes. After `stop` or `destroy` begins, a later
1010
+ * call settles `false`, because teardown cannot confirm delivery for bytes it is about to
1011
+ * discard.
1012
+ *
1013
+ * @param bytes - The payload to write, already framed by the caller
1014
+ * @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`)
1015
+ *
1016
+ * @example
1017
+ * ```ts
1018
+ * import { Supervisor } from '@orkestrel/process/server'
1019
+ *
1020
+ * const engine = new Supervisor(
1021
+ * {
1022
+ * command: { file: 'node', arguments: ['-e', 'process.stdin.pipe(process.stdout)'] },
1023
+ * workspace: process.cwd(),
1024
+ * writable: true,
1025
+ * },
1026
+ * {
1027
+ * chunk: () => undefined,
1028
+ * fault: () => undefined,
1029
+ * close: () => undefined,
1030
+ * terminal: () => undefined,
1031
+ * teardown: () => undefined,
1032
+ * },
1033
+ * )
1034
+ * const accepted = await engine.deliver(new TextEncoder().encode('ping\n'))
1035
+ * accepted // true
1036
+ * await engine.destroy()
1037
+ * ```
1038
+ */
1039
+ deliver(bytes: Uint8Array): Promise<boolean>;
1040
+ /**
1041
+ * Closes the standard-input channel while leaving the child running.
1042
+ *
1043
+ * @remarks
1044
+ * Never rejects, and terminates nothing: no signal is sent, `stopping` stays false, no drain
1045
+ * window is armed, and the terminal moment does not arrive. The child observes end of input and
1046
+ * decides for itself what to do about it, which is what separates this from `stop`.
1047
+ *
1048
+ * Every call shares one barrier, and it resolves after the host flushes the writes it had already
1049
+ * accepted, or reports that it cannot. A `deliver` after this call resolves `false`, because the
1050
+ * host stops reporting the channel writable the moment it is ended. That same flag keeps the
1051
+ * ended channel quiet for its remaining life, so a later host fault on it settles pending writes
1052
+ * and reaches no face. After `stop` or `destroy` has begun, or after the terminal moment, the
1053
+ * call resolves and changes nothing, because the channel is already being discarded.
1054
+ *
1055
+ * @returns The stable barrier shared by every call
1056
+ */
1057
+ end(): Promise<void>;
1058
+ /**
1059
+ * Terminates the child process tree and reaches the terminal observation moment.
1060
+ *
1061
+ * @remarks
1062
+ * Never rejects, and every call shares one termination. After the termination sequence returns,
1063
+ * confirmed or not, it waits at most `drain` for the read channels to close, then cuts them off
1064
+ * and settles `exit` when they remain open. A cutoff reached before the native exit reports the
1065
+ * `code` and `signal` the host had recorded by then, which is `null` for a child still running.
1066
+ *
1067
+ * @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
1068
+ */
1069
+ stop(): Promise<boolean>;
1070
+ /**
1071
+ * Stops the child and releases the composing face after the terminal state freezes.
1072
+ *
1073
+ * @remarks
1074
+ * Always resolves, including when termination was never confirmed. Every call shares one barrier.
1075
+ *
1076
+ * @returns The stable barrier shared by every call
1077
+ */
1078
+ destroy(): Promise<void>;
1079
+ }
1080
+
1081
+ /**
1082
+ * Represents the composing face's callbacks for each lifecycle moment of one supervised child.
1083
+ *
1084
+ * @remarks
1085
+ * `Process` and `Session` each construct one and hand it to the supervision engine, which captures
1086
+ * every callback before anything is read or spawned, so the first moment the child can produce
1087
+ * already has somewhere to go. `chunk` receives each decoded standard-error fragment, `fault` the
1088
+ * host error that ended the run, `close` the moment the read channels closed, `terminal` the frozen
1089
+ * exit state, and `teardown` the release of whatever the face still holds. `relieve` is optional
1090
+ * because a face that never pauses the child's output holds no backpressure to release.
1091
+ */
1092
+ export declare interface SupervisorFace {
1093
+ /** Receives one decoded standard-error fragment. */
1094
+ readonly chunk: (text: string) => void;
1095
+ /** Receives the host error that ended the run. */
1096
+ readonly fault: (cause: unknown) => void;
1097
+ /** Reports that a termination began, so a face holding output backpressure releases it. */
1098
+ readonly relieve?: () => void;
1099
+ /** Reports that the child's read channels closed. */
1100
+ readonly close: () => void;
1101
+ /** Receives the frozen terminal state. */
1102
+ readonly terminal: (exit: ProcessExit) => void;
1103
+ /** Releases whatever the face still holds after the terminal moment. */
1104
+ readonly teardown: () => void;
1105
+ }
909
1106
 
910
1107
  /**
911
1108
  * Trims a buffer to at most `limit` leading bytes without splitting a UTF-8 sequence.
912
1109
  *
913
1110
  * @remarks
914
- * Keeps the head — the captured start of a one-shot run's output. When the cut point lands inside
915
- * a multibyte sequence, the end retreats to the sequence's start so the retained bytes always end
916
- * on a code-point boundary and decode without a replacement character.
1111
+ * Keeps the head — the captured start of a one-shot run's output. The end retreats only when a
1112
+ * sequence genuinely spans the cut: the byte at `limit` carries the continuation bit pattern, and a
1113
+ * lead byte within the preceding three bytes declares a length that reaches it. The retained bytes
1114
+ * then end on a code-point boundary and decode without a replacement character. A byte at `limit`
1115
+ * that carries the continuation pattern without such a lead byte is invalid UTF-8 rather than a
1116
+ * split sequence, so the full `limit` survives instead of a valid byte being dropped for it.
917
1117
  *
918
1118
  * @param bytes - The accumulated bytes
919
1119
  * @param limit - The maximum retained byte count
@@ -1051,14 +1251,14 @@ export declare function validateWorkspace(workspace: string | undefined): void;
1051
1251
  *
1052
1252
  * @param child - The child boundary
1053
1253
  * @param timeout - The milliseconds to wait before giving up
1054
- * @returns True when the host close arrived inside the deadline; false otherwise
1254
+ * @returns True if the host close arrived inside the deadline; false otherwise
1055
1255
  *
1056
1256
  * @example
1057
1257
  * ```ts
1058
1258
  * const closed = await waitForClose(child, 5_000)
1059
1259
  * ```
1060
1260
  */
1061
- export declare function waitForClose(child: Pick<ProcessChild, 'once' | 'off'>, timeout: number): Promise<boolean>;
1261
+ export declare function waitForClose(child: Pick<ProcessChildInterface, 'once' | 'off'>, timeout: number): Promise<boolean>;
1062
1262
 
1063
1263
  /**
1064
1264
  * Waits for one child process's native exit, bounded by a deadline.
@@ -1072,6 +1272,6 @@ export declare function waitForClose(child: Pick<ProcessChild, 'once' | 'off'>,
1072
1272
  * await waitForExit(child, 5_000)
1073
1273
  * ```
1074
1274
  */
1075
- export declare function waitForExit(child: Pick<ProcessChild, 'exitCode' | 'signalCode' | 'once' | 'off'>, timeout: number): Promise<void>;
1275
+ export declare function waitForExit(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode' | 'once' | 'off'>, timeout: number): Promise<void>;
1076
1276
 
1077
1277
  export { }