@orkestrel/process 0.0.2 → 0.0.3

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.
@@ -10,15 +10,67 @@ import { EmitterInterface } from '@orkestrel/emitter';
10
10
  */
11
11
  export declare function createDuplicateError(id: string): ProcessError;
12
12
 
13
+ /**
14
+ * Creates the failure raised when a public input is refused before anything is spawned.
15
+ *
16
+ * @param subject - The rejected input named as the caller wrote it, such as `option 'grace'`
17
+ * @param value - The rejected value, carried as `context.value`
18
+ * @returns A typed validation failure
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * createInvalidError("option 'grace'", -1).code // 'invalid'
23
+ * ```
24
+ */
25
+ export declare function createInvalidError(subject: string, value: unknown): ProcessError;
26
+
27
+ /**
28
+ * Creates the failure raised when a launch is attempted on a registry that is being destroyed.
29
+ *
30
+ * @param id - The id the refused launch asked for
31
+ * @returns A typed protocol failure
32
+ */
33
+ export declare function createProtocolError(id: string): ProcessError;
34
+
13
35
  /**
14
36
  * Creates the failure raised when a run does not complete successfully and rejection is requested.
15
37
  *
38
+ * @remarks
39
+ * The category is `timeout` only when the run's own timeout elapsed; every other failure, including
40
+ * an abort and an output overflow, is a `spawn` failure carrying its {@link RunResult}.
41
+ *
16
42
  * @param result - The buffered run outcome that failed
17
- * @param cause - The underlying spawn error, when one ended the run
43
+ * @param cause - The underlying host fault, when one ended the run
18
44
  * @returns A typed run failure carrying its {@link RunResult}
19
45
  */
20
46
  export declare function createRunError(result: RunResult, cause?: unknown): ProcessError;
21
47
 
48
+ /**
49
+ * Options for a detached fire-and-forget spawn.
50
+ *
51
+ * @remarks
52
+ * A detached child owns no stdio and is never awaited, so the contract carries only the directory it
53
+ * starts in. Its environment comes from the command's own `environment` and `isolated`.
54
+ */
55
+ export declare interface DetachOptions {
56
+ /** The working directory. Default: the current working directory. */
57
+ readonly workspace?: string;
58
+ }
59
+
60
+ /**
61
+ * Lookup inputs for resolving a command file to an executable path.
62
+ *
63
+ * @remarks
64
+ * `workspace` is searched before `PATH`, matching Windows command semantics. `environment` is the
65
+ * child's effective environment, so the lookup reads the same `PATH` and `PATHEXT` the child will.
66
+ */
67
+ export declare interface ExecutableOptions {
68
+ /** The directory searched first. Default: the current working directory. */
69
+ readonly workspace?: string;
70
+ /** The child's effective environment. Default: the parent process environment. */
71
+ readonly environment?: Readonly<Record<string, string | undefined>>;
72
+ }
73
+
22
74
  /**
23
75
  * Checks whether an unknown value is a {@link ProcessError}.
24
76
  *
@@ -33,46 +85,63 @@ export declare function createRunError(result: RunResult, cause?: unknown): Proc
33
85
  */
34
86
  export declare function isProcessError(value: unknown): value is ProcessError;
35
87
 
88
+ /** The default soft high-water mark in bytes for a supervised {@link ProcessInterface} line backlog. */
89
+ export declare const PROCESS_BACKLOG = 10485760;
90
+
91
+ /** The window in milliseconds a termination waits for the child's native exit after the final kill. */
92
+ export declare const PROCESS_CONFIRMATION = 5000;
93
+
36
94
  /** The default maximum retained stderr tail in bytes for a supervised {@link ProcessInterface}. */
37
95
  export declare const PROCESS_EVIDENCE = 2048;
38
96
 
39
- /** The default cooperative window in milliseconds between `SIGTERM` and `SIGKILL` during termination. */
97
+ /** The default cooperative POSIX window in milliseconds between `SIGTERM` and `SIGKILL` during termination. */
40
98
  export declare const PROCESS_GRACE = 5000;
41
99
 
42
100
  /** The default maximum captured bytes for a one-shot run's stdout and stderr, each. */
43
101
  export declare const PROCESS_OUTPUT = 10485760;
44
102
 
103
+ /** The executable extensions a Windows lookup applies when the environment declares no `PATHEXT`. */
104
+ export declare const PROCESS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
105
+
106
+ /** The largest timer delay in milliseconds the host schedules without truncating it to one. */
107
+ export declare const PROCESS_TIMER = 2147483647;
108
+
45
109
  /**
46
110
  * The public contracts for `@orkestrel/process`: a typed child-process toolkit.
47
111
  *
48
112
  * @remarks
49
113
  * Three tiers, smallest to largest:
50
114
  *
51
- * - **{@link ProcessInterface}** — one supervised child with eagerly framed stdout lines, a
52
- * byte-bounded stderr tail, a live stderr event, a writable stdin channel, a typed lifecycle
53
- * {@link ProcessEventMap} emitter, and bounded `SIGTERM` → grace → `SIGKILL` termination. The
54
- * low-level streaming primitive.
115
+ * - **{@link ProcessInterface}** — one supervised child with framed stdout lines under a bounded
116
+ * backlog, a byte-bounded stderr tail, a live stderr event, a writable stdin channel, a typed
117
+ * lifecycle {@link ProcessEventMap} emitter, and bounded termination. The low-level streaming
118
+ * primitive.
55
119
  * - **{@link RunResult} / run** — a one-shot runner that buffers a child to completion and settles
56
120
  * with its output and exit, the ergonomic layer for fire-and-collect commands.
57
121
  * - **{@link ProcessManagerInterface}** — a keyed registry of live {@link ProcessInterface}
58
122
  * children, launched and stopped by id, observed through its own {@link ProcessManagerEventMap}.
59
123
  *
60
- * Every contract here is host-independent (`AbortSignal`, `AsyncIterable`, `Promise`, and plain
61
- * `string` signal names). The Node implementations live in `@orkestrel/process/server`.
124
+ * Every contract here is host-independent (`AbortSignal`, `AsyncIterable`, `Promise`, `Uint8Array`,
125
+ * and plain `string` signal names). The Node implementations live in `@orkestrel/process/server`.
62
126
  */
63
127
  /**
64
128
  * One spawnable command: the executable, its argument vector, and optional environment overrides
65
129
  * and initial standard input.
66
130
  *
67
131
  * @remarks
68
- * `environment` merges over the parent process environment; an `undefined` value unsets a key.
69
- * `input` is written to the child's stdin immediately after spawn.
132
+ * `environment` merges over the parent process environment unless `isolated` is `true`, and an
133
+ * `undefined` value unsets a key. On Windows the merge is case-insensitive and the last writer
134
+ * wins, matching how the host resolves an environment variable. `input` is written to the child's
135
+ * stdin immediately after spawn. Every string here is spawn-bound: an empty `file`, or a NUL
136
+ * character anywhere, is refused with a {@link ProcessError} coded `invalid`.
70
137
  */
71
138
  export declare interface ProcessCommand {
72
139
  readonly file: string;
73
140
  readonly arguments: readonly string[];
74
141
  readonly environment?: Readonly<Record<string, string | undefined>>;
75
142
  readonly input?: string;
143
+ /** If `true`, the child environment is `environment` alone; if `false` or omitted, it merges over the parent environment. */
144
+ readonly isolated?: boolean;
76
145
  }
77
146
 
78
147
  /** A child-process failure with a stable machine-readable category. */
@@ -92,7 +161,7 @@ export declare class ProcessError extends Error {
92
161
  }
93
162
 
94
163
  /** The machine-readable {@link ProcessError} categories. */
95
- export declare type ProcessErrorCode = 'spawn' | 'timeout' | 'duplicate' | 'protocol';
164
+ export declare type ProcessErrorCode = 'spawn' | 'timeout' | 'duplicate' | 'protocol' | 'invalid';
96
165
 
97
166
  /** Structured context carried by a {@link ProcessError}. */
98
167
  export declare interface ProcessErrorContext {
@@ -148,19 +217,25 @@ export declare interface ProcessExit {
148
217
  }
149
218
 
150
219
  /**
151
- * One supervised child process with eagerly framed output and bounded termination.
220
+ * One supervised child process with framed output, a bounded backlog, and bounded termination.
152
221
  *
153
222
  * @remarks
154
- * `lines` is pumped eagerly: stdout is drained whether or not a consumer iterates, so `exit`
155
- * resolves and a late consumer still receives every line. `evidence` is the decoded, byte-bounded
156
- * stderr tail — the diagnostic to attach to a failed exit. The typed `emitter` carries the live
157
- * `stderr` chunks, the child `error` cause, and the terminal `exit`, alongside the `exit` promise.
158
- * `send` never throws; it returns whether the line reached an open channel. `stop` is idempotent.
223
+ * `lines` is pumped as soon as the child writes, and it is a single-consumer stream: each line goes
224
+ * to exactly one waiting iterator, so two iterators split the output between them rather than each
225
+ * receiving all of it. The policy for an unconsumed backlog follows
226
+ * consumer intent. Once an iterator has been requested, stdout pauses at the `backlog` mark and
227
+ * resumes at half of it, so the consumer loses nothing and the child feels real backpressure. While
228
+ * no iterator has ever been requested, stdout keeps draining so `exit` still resolves, and retention
229
+ * stops at the mark: a consumer attaching after that point receives the retained head, a gap, then
230
+ * the live stream. `evidence` is the decoded, byte-bounded stderr tail — the diagnostic to attach to
231
+ * a failed exit. The typed `emitter` carries the live `stderr` chunks, the child `error` cause, and
232
+ * the terminal `exit`, alongside the `exit` promise. `stop` and `destroy` are idempotent and never
233
+ * reject.
159
234
  */
160
235
  export declare interface ProcessInterface {
161
236
  /** The typed lifecycle observation surface. */
162
237
  readonly emitter: EmitterInterface<ProcessEventMap>;
163
- /** The eagerly captured stdout lines, in arrival order, ending when the child's stdout closes. */
238
+ /** The captured stdout lines, in arrival order, for one consumer, ending when the child's stdout closes. */
164
239
  readonly lines: AsyncIterable<string>;
165
240
  /** The decoded byte-bounded stderr tail. */
166
241
  readonly evidence: string;
@@ -169,18 +244,35 @@ export declare interface ProcessInterface {
169
244
  /**
170
245
  * Write one line to the open standard-input channel.
171
246
  *
247
+ * @remarks
248
+ * Never rejects. The promise settles when the host reports the line handled, so a line written
249
+ * to a child that is not reading stays pending until the child drains it or the channel closes.
250
+ * Every terminal teardown path destroys stdin, so a pending write always settles by teardown. A
251
+ * caller that needs its own deadline arms a timer and calls `stop`.
252
+ *
172
253
  * @param text - The line text without its trailing newline
173
- * @returns True when the channel accepted the line without backpressure; false otherwise
254
+ * @returns True when the line reached the host without error; false when the channel was closed, destroyed, ended, or the write failed
174
255
  */
175
- send(text: string): boolean;
256
+ send(text: string): Promise<boolean>;
176
257
  /**
177
258
  * Terminate the child process tree and await its observed exit.
178
259
  *
179
- * @returns A promise that resolves after bounded termination
260
+ * @remarks
261
+ * Never rejects. On Windows the whole tree is killed immediately through `taskkill`, with a
262
+ * direct kill as the fallback; on a POSIX host the process group receives `SIGTERM`, then
263
+ * `SIGKILL` after `grace`. No signal is initiated after the child's native exit is observed; the
264
+ * window between initiating a signal and the host delivering it belongs to the operating system.
265
+ *
266
+ * @returns True when the child's native exit was observed; false when the confirmation deadline elapsed without it
180
267
  */
181
- stop(): Promise<void>;
268
+ stop(): Promise<boolean>;
182
269
  /**
183
- * Stop the child and destroy the observation emitter.
270
+ * Stop the child, close its standard-input channel, and destroy the observation emitter.
271
+ *
272
+ * @remarks
273
+ * Always resolves, including when termination was never confirmed. Resolving does not imply the
274
+ * child's stdio has closed: a descendant holding an inherited pipe keeps the close event pending,
275
+ * so `exit` and `lines` can still be outstanding after this barrier settles.
184
276
  *
185
277
  * @returns The stable barrier shared by every call
186
278
  */
@@ -206,10 +298,12 @@ export declare type ProcessManagerEventMap = {
206
298
  *
207
299
  * @remarks
208
300
  * A child that settles removes itself from the registry, so `count` and `processes` reflect only
209
- * live children, and its departure emits `exit`. `launch` throws a {@link ProcessError} coded
210
- * `duplicate` when the id is already live — spawn faults surface through the returned child's
211
- * `exit`, not from `launch`. The typed `emitter` carries the `launch` and `exit` moments across
212
- * every child.
301
+ * live children, and its departure emits `exit`. Eviction follows the child's own `exit` promise,
302
+ * which no listener can forge, so it lands one microtask after the child's public `exit` event: a
303
+ * listener on that event still sees the child registered. `launch` throws a {@link ProcessError}
304
+ * coded `duplicate` when the id is already live and `protocol` after `destroy` has begun — spawn
305
+ * faults surface through the returned child's `exit`, not from `launch`. The typed `emitter` carries
306
+ * the `launch` and `exit` moments across every child.
213
307
  */
214
308
  export declare interface ProcessManagerInterface {
215
309
  /** The typed fleet-level observation surface. */
@@ -232,35 +326,49 @@ export declare interface ProcessManagerInterface {
232
326
  /**
233
327
  * Spawn and register one child under `id`.
234
328
  *
329
+ * @remarks
330
+ * Every option is read before the child is spawned, so a caller's own option getter runs while
331
+ * nothing has started and a throw from one strands no process. A getter that begins `destroy`
332
+ * without throwing is the one remaining race, and it leaves a bounded residual: the child is
333
+ * already spawned, so the launch is refused with `protocol` and that child is torn down
334
+ * asynchronously, bounded by `grace` plus the confirmation window. The `destroy` barrier settled
335
+ * before the refusal, so awaiting it does not cover that teardown.
336
+ *
235
337
  * @param id - The registry key, unique among live children
236
338
  * @param options - The child construction options
237
339
  * @returns The launched child
238
- * @throws A {@link ProcessError} coded `duplicate` when `id` is already live
340
+ * @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
239
341
  */
240
342
  launch(id: string, options: ProcessOptions): ProcessInterface;
241
343
  /**
242
344
  * Terminate the named children and await their exit.
243
345
  *
244
346
  * @param ids - The registry keys to stop
245
- * @returns True when every named child stopped, false when any id was not live
347
+ * @returns True when every named child was live and its exit was confirmed; false otherwise
246
348
  */
247
349
  stop(ids: readonly string[]): Promise<boolean>;
248
350
  /**
249
351
  * Terminate one child and await its exit.
250
352
  *
251
353
  * @param id - The registry key to stop
252
- * @returns True when the child was live and stopped, false when the id was not live
354
+ * @returns True when the child was live and its exit was confirmed; false when the id was not live or the confirmation deadline elapsed
253
355
  */
254
356
  stop(id: string): Promise<boolean>;
255
357
  /**
256
358
  * Terminate every live child and await their exit.
257
359
  *
258
- * @returns A promise that resolves after all children stop
360
+ * @returns A promise that resolves after every child stops
259
361
  */
260
362
  stop(): Promise<void>;
261
363
  /**
262
364
  * Stop every child, then destroy the registry emitter last.
263
365
  *
366
+ * @remarks
367
+ * Always resolves, and refuses a later `launch` with a {@link ProcessError} coded `protocol`.
368
+ * Every child is destroyed, not merely stopped, so each child's own observation emitter is
369
+ * destroyed too and every subscription on it goes silently inert. The registry emitter is
370
+ * destroyed last.
371
+ *
264
372
  * @returns The stable barrier shared by every call
265
373
  */
266
374
  destroy(): Promise<void>;
@@ -282,10 +390,13 @@ export declare interface ProcessManagerOptions {
282
390
  * Construction options for one supervised child process.
283
391
  *
284
392
  * @remarks
285
- * `grace` is the sole timing knob: after `stop`, the child is sent `SIGTERM`, then `SIGKILL` if it
286
- * has not exited within `grace` milliseconds. There is no completion deadline — a caller that wants
287
- * one arms its own timer and calls `stop`. `on` installs initial {@link ProcessEventMap} listeners
288
- * and `error` receives isolated listener failures.
393
+ * `grace` is the cooperative window between `SIGTERM` and `SIGKILL` on a POSIX host; Windows has no
394
+ * cooperative phase, so the value is unused there. There is no completion deadline — a caller that
395
+ * wants one arms its own timer and calls `stop`. `backlog` bounds the unconsumed `lines` backlog.
396
+ * `on` installs initial {@link ProcessEventMap} listeners and `error` receives isolated listener
397
+ * failures. Every numeric option is validated at construction: a timer value outside
398
+ * `[0, PROCESS_TIMER]`, a negative or fractional byte value, or a `backlog` below `1` throws a
399
+ * {@link ProcessError} coded `invalid`.
289
400
  */
290
401
  export declare interface ProcessOptions {
291
402
  readonly on?: EmitterHooks<ProcessEventMap>;
@@ -293,24 +404,58 @@ export declare interface ProcessOptions {
293
404
  readonly command: ProcessCommand;
294
405
  /** The working directory the child runs in. */
295
406
  readonly workspace: string;
296
- /** Cooperative termination window in milliseconds between `SIGTERM` and `SIGKILL`. */
297
- readonly grace: number;
407
+ /** Cooperative POSIX window in milliseconds between `SIGTERM` and `SIGKILL`. Default: {@link PROCESS_GRACE}. */
408
+ readonly grace?: number;
298
409
  /** Maximum retained stderr tail in bytes. Default: {@link PROCESS_EVIDENCE}. */
299
410
  readonly evidence?: number;
411
+ /** Soft high-water mark in bytes for the unconsumed `lines` backlog. Default: {@link PROCESS_BACKLOG}. */
412
+ readonly backlog?: number;
300
413
  /** If `true`, stdin stays open for {@link ProcessInterface.send}; if `false` or omitted, stdin closes after any initial `input`. */
301
414
  readonly writable?: boolean;
302
415
  /** Aborting this signal terminates the child through the same bounded `stop`. */
303
416
  readonly signal?: AbortSignal;
304
417
  }
305
418
 
419
+ /**
420
+ * The captured bytes and terminal facts one settled {@link RunResult} is built from.
421
+ *
422
+ * @remarks
423
+ * Both byte fields are trimmed to `limit` on a code-point boundary when the result is built, so a
424
+ * caller passes the raw retained head and never a decoded string. `cause` carries the host fault
425
+ * that ended the run, when one did; its presence alone marks the run failed.
426
+ */
427
+ export declare interface RunInput {
428
+ /** The diagnostic command line. */
429
+ readonly command: string;
430
+ /** The retained standard-output bytes. */
431
+ readonly stdout: Uint8Array;
432
+ /** The retained standard-error bytes. */
433
+ readonly stderr: Uint8Array;
434
+ readonly code: number | null;
435
+ readonly signal: string | null;
436
+ /** If `true`, the run's own timeout elapsed; if `false`, it did not. */
437
+ readonly expired: boolean;
438
+ /** If `true`, the caller's signal aborted the run; if `false`, it did not. */
439
+ readonly aborted: boolean;
440
+ /** If `true`, a stream exceeded `limit`; if `false`, both fit. */
441
+ readonly truncated: boolean;
442
+ /** The maximum retained bytes for each stream. */
443
+ readonly limit: number;
444
+ /** The host fault that ended the run, when one did. */
445
+ readonly cause?: unknown;
446
+ }
447
+
306
448
  /**
307
449
  * Options for a one-shot run.
308
450
  *
309
451
  * @remarks
310
- * A run is a fire-and-collect function, not a lifecycle entity, so it carries no emitter. `reject`
311
- * follows the command-runner convention: by default a non-zero exit rejects with a
312
- * {@link ProcessError} carrying the {@link RunResult}; `reject: false` resolves with the result
313
- * instead, so the caller inspects `failed`.
452
+ * A run is a fire-and-collect function, not a lifecycle entity, so it carries no emitter. `strict`
453
+ * decides how a failure is delivered: by default a non-zero exit rejects with a
454
+ * {@link ProcessError} carrying the {@link RunResult}; `strict: false` resolves with the result
455
+ * instead, so the caller inspects `failed`. An invalid option or command rejects before the child is
456
+ * spawned, with a {@link ProcessError} coded `invalid`. An unbounded run awaits stdio completion
457
+ * rather than process exit, so give `timeout` a value wherever a descendant may inherit the child's
458
+ * stdio and hold the pipe open past the child's own exit.
314
459
  */
315
460
  export declare interface RunOptions {
316
461
  /** The working directory. Default: the current working directory. */
@@ -321,12 +466,12 @@ export declare interface RunOptions {
321
466
  readonly input?: string;
322
467
  /** Milliseconds before the child is terminated. `0` or omitted disables the timeout. */
323
468
  readonly timeout?: number;
324
- /** Cooperative window between `SIGTERM` and `SIGKILL` when terminating. Default: {@link PROCESS_GRACE}. */
469
+ /** Cooperative POSIX window between `SIGTERM` and `SIGKILL` when terminating. Default: {@link PROCESS_GRACE}. */
325
470
  readonly grace?: number;
326
- /** Aborting this signal terminates the run. */
471
+ /** Aborting this signal terminates the run and reports `aborted`. */
327
472
  readonly signal?: AbortSignal;
328
473
  /** If `false`, resolve with the result on failure instead of rejecting. Default: `true`. */
329
- readonly reject?: boolean;
474
+ readonly strict?: boolean;
330
475
  /** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
331
476
  readonly limit?: number;
332
477
  }
@@ -335,22 +480,71 @@ export declare interface RunOptions {
335
480
  * The settled outcome of a one-shot run: the buffered output and the terminal state.
336
481
  *
337
482
  * @remarks
338
- * `failed` is `true` when the child exited non-zero, was killed by a signal, timed out, or failed to
339
- * spawn. `timedOut` is `true` only when the run's own `timeout` elapsed.
483
+ * `failed` is `true` when the child exited non-zero, was killed by a signal, expired, was aborted, or
484
+ * failed to spawn. `expired` and `aborted` are the two ways the run ended the child rather than the
485
+ * child ending itself, and only the first of them observed is recorded. `truncated` is independent of
486
+ * both: it reports that a stream exceeded `limit`, which fails a synchronous run and does not fail an
487
+ * asynchronous one.
340
488
  */
341
489
  export declare interface RunResult {
342
490
  /** The command line that was run, for diagnostics. */
343
491
  readonly command: string;
344
- /** The complete captured standard output, byte-bounded by `limit`. */
492
+ /** The captured standard output, byte-bounded by `limit`. */
345
493
  readonly stdout: string;
346
- /** The complete captured standard error, byte-bounded by `limit`. */
494
+ /** The captured standard error, byte-bounded by `limit`. */
347
495
  readonly stderr: string;
348
496
  readonly code: number | null;
349
497
  readonly signal: string | null;
350
498
  /** True if the run did not complete successfully. */
351
499
  readonly failed: boolean;
352
500
  /** True if the run's `timeout` elapsed before completion. */
353
- readonly timedOut: boolean;
501
+ readonly expired: boolean;
502
+ /** True if the caller's `signal` aborted the run before completion. */
503
+ readonly aborted: boolean;
504
+ /** True if either stream exceeded `limit`, so the captured text is the retained head. */
505
+ readonly truncated: boolean;
506
+ }
507
+
508
+ /**
509
+ * Options for a synchronous one-shot run.
510
+ *
511
+ * @remarks
512
+ * The synchronous host offers neither a cooperative termination window nor in-flight cancellation,
513
+ * so this contract carries no `grace` and no `signal`. A `timeout` and an output overflow both end
514
+ * the child with `SIGKILL`; an overflow reports `truncated` and `failed` together, which is where
515
+ * the synchronous and asynchronous runners genuinely differ.
516
+ */
517
+ export declare interface RunSyncOptions {
518
+ /** The working directory. Default: the current working directory. */
519
+ readonly workspace?: string;
520
+ /** Environment overrides merged over the parent environment; an `undefined` value unsets a key. */
521
+ readonly environment?: Readonly<Record<string, string | undefined>>;
522
+ /** Standard input written to the child. */
523
+ readonly input?: string;
524
+ /** Milliseconds before the host kills the child. `0` or omitted disables the timeout. */
525
+ readonly timeout?: number;
526
+ /** If `false`, return the result on failure instead of throwing. Default: `true`. */
527
+ readonly strict?: boolean;
528
+ /** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
529
+ readonly limit?: number;
530
+ }
531
+
532
+ /**
533
+ * The resolved spawn form of one command: the executable to launch, the argument vector to pass,
534
+ * and whether the host receives that vector verbatim.
535
+ *
536
+ * @remarks
537
+ * No spawn in this package uses an implicit shell. `verbatim` is `true` only for a Windows `.cmd` or
538
+ * `.bat` script, which runs through an explicitly quoted `cmd.exe /d /s /c` command line, and an
539
+ * argument that batch target could corrupt — one carrying `%`, which `cmd.exe` expands before it
540
+ * parses quotes — is refused rather than passed. A shell metacharacter in an argument is therefore
541
+ * data rather than syntax on every path.
542
+ */
543
+ export declare interface SpawnInput {
544
+ readonly file: string;
545
+ readonly arguments: readonly string[];
546
+ /** If `true`, pass the argument vector to the host verbatim; if `false`, let the host quote it. */
547
+ readonly verbatim: boolean;
354
548
  }
355
549
 
356
550
  export { }