@kadi.build/core 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +424 -1
  2. package/agent.json +19 -0
  3. package/dist/agent-json.d.ts +231 -0
  4. package/dist/agent-json.d.ts.map +1 -0
  5. package/dist/agent-json.js +554 -0
  6. package/dist/agent-json.js.map +1 -0
  7. package/dist/client.d.ts +34 -0
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +50 -0
  10. package/dist/client.js.map +1 -1
  11. package/dist/errors.d.ts +1 -1
  12. package/dist/errors.d.ts.map +1 -1
  13. package/dist/errors.js.map +1 -1
  14. package/dist/index.d.ts +5 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +8 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/process-manager.d.ts +235 -0
  19. package/dist/process-manager.d.ts.map +1 -0
  20. package/dist/process-manager.js +647 -0
  21. package/dist/process-manager.js.map +1 -0
  22. package/dist/stdio-framing.d.ts +88 -0
  23. package/dist/stdio-framing.d.ts.map +1 -0
  24. package/dist/stdio-framing.js +194 -0
  25. package/dist/stdio-framing.js.map +1 -0
  26. package/dist/transports/stdio.d.ts.map +1 -1
  27. package/dist/transports/stdio.js +3 -181
  28. package/dist/transports/stdio.js.map +1 -1
  29. package/dist/types.d.ts +256 -0
  30. package/dist/types.d.ts.map +1 -1
  31. package/dist/utils.d.ts +107 -0
  32. package/dist/utils.d.ts.map +1 -0
  33. package/dist/utils.js +212 -0
  34. package/dist/utils.js.map +1 -0
  35. package/package.json +3 -1
  36. package/scripts/symlink.mjs +131 -0
  37. package/src/agent-json.ts +655 -0
  38. package/src/client.ts +56 -0
  39. package/src/errors.ts +15 -0
  40. package/src/index.ts +32 -0
  41. package/src/process-manager.ts +821 -0
  42. package/src/stdio-framing.ts +227 -0
  43. package/src/transports/stdio.ts +4 -221
  44. package/src/types.ts +277 -0
  45. package/src/utils.ts +246 -0
@@ -0,0 +1,647 @@
1
+ /**
2
+ * ProcessManager for kadi-core
3
+ *
4
+ * Manages background child processes with three execution modes:
5
+ *
6
+ * - **headless**: Fire-and-forget. No communication channel.
7
+ * - **piped**: stdout/stderr are streamed back and buffered.
8
+ * - **bridge**: Full JSON-RPC stdio bridge (Content-Length framing).
9
+ *
10
+ * Primary use case: Running long tasks (builds, deploys, inference) in the
11
+ * background so the main agent's event loop stays free for broker heartbeats.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ProcessManager } from '@kadi.build/core';
16
+ *
17
+ * const pm = new ProcessManager();
18
+ *
19
+ * // Headless build
20
+ * const build = await pm.spawn('build', {
21
+ * command: 'docker', args: ['build', '.'], mode: 'headless',
22
+ * });
23
+ * const status = pm.getStatus('build');
24
+ *
25
+ * // Piped deploy with live output
26
+ * const deploy = await pm.spawn('deploy', {
27
+ * command: 'kadi', args: ['deploy'], mode: 'piped',
28
+ * });
29
+ * deploy.on('stdout', (data) => console.log(data));
30
+ *
31
+ * // Bridge mode for interactive workers
32
+ * const worker = await pm.spawn('worker', {
33
+ * command: 'python3', args: ['worker.py'], mode: 'bridge',
34
+ * });
35
+ * const result = await worker.request('run-inference', { prompt: 'hello' });
36
+ * ```
37
+ */
38
+ import { spawn } from 'child_process';
39
+ import { EventEmitter } from 'events';
40
+ import { KadiError } from './errors.js';
41
+ import { StdioMessageReader, StdioMessageWriter } from './stdio-framing.js';
42
+ import * as protocol from './protocol.js';
43
+ // ═══════════════════════════════════════════════════════════════════════
44
+ // CONSTANTS
45
+ // ═══════════════════════════════════════════════════════════════════════
46
+ const DEFAULT_KILL_GRACE_PERIOD = 5000;
47
+ const DEFAULT_MAX_OUTPUT_BUFFER = 10 * 1024 * 1024; // 10 MB
48
+ // ═══════════════════════════════════════════════════════════════════════
49
+ // MANAGED PROCESS
50
+ // ═══════════════════════════════════════════════════════════════════════
51
+ /**
52
+ * A handle to a spawned background process.
53
+ *
54
+ * Provides event subscription, lifecycle management, and (in bridge mode)
55
+ * JSON-RPC request/response communication.
56
+ */
57
+ export class ManagedProcess extends EventEmitter {
58
+ /** Unique identifier */
59
+ id;
60
+ /** OS process ID */
61
+ pid;
62
+ /** Execution mode */
63
+ mode;
64
+ /** Internal state */
65
+ _state = 'running';
66
+ _exitCode = null;
67
+ _signal = null;
68
+ _startedAt;
69
+ _endedAt = null;
70
+ /** Command info for getInfo() */
71
+ _command;
72
+ _args;
73
+ _cwd;
74
+ /** Output buffering (piped mode) */
75
+ _stdout = '';
76
+ _stderr = '';
77
+ _maxOutputBuffer;
78
+ /** Bridge mode internals */
79
+ _reader = null;
80
+ _writer = null;
81
+ _bridgeIdCounter = 1;
82
+ /** The underlying child process */
83
+ _proc;
84
+ /** Timeout timer for auto-kill */
85
+ _timeoutTimer = null;
86
+ /** Kill grace period */
87
+ _killGracePeriod;
88
+ /** Waiters for the exit event */
89
+ _exitWaiters = [];
90
+ constructor(id, proc, options) {
91
+ super();
92
+ this.id = id;
93
+ this._proc = proc;
94
+ this.pid = proc.pid;
95
+ this.mode = options.mode;
96
+ this._command = options.command;
97
+ this._args = options.args ?? [];
98
+ this._cwd = options.cwd ?? process.cwd();
99
+ this._startedAt = new Date();
100
+ this._killGracePeriod = options.killGracePeriod ?? DEFAULT_KILL_GRACE_PERIOD;
101
+ this._maxOutputBuffer = options.maxOutputBuffer ?? DEFAULT_MAX_OUTPUT_BUFFER;
102
+ // Set up auto-kill timeout
103
+ if (options.timeout && options.timeout > 0) {
104
+ this._timeoutTimer = setTimeout(() => {
105
+ this.kill().catch(() => { });
106
+ }, options.timeout);
107
+ }
108
+ // Set up process exit handler
109
+ proc.on('exit', (code, signal) => {
110
+ this.handleExit(code, signal);
111
+ });
112
+ proc.on('error', (error) => {
113
+ if (this._state === 'running') {
114
+ this._state = 'errored';
115
+ this._endedAt = new Date();
116
+ this.emit('error', error);
117
+ this.resolveExitWaiters();
118
+ }
119
+ });
120
+ // Set up output streaming based on mode
121
+ if (options.mode === 'piped') {
122
+ this.setupPipedMode(proc);
123
+ }
124
+ else if (options.mode === 'bridge') {
125
+ this.setupBridgeMode(proc, options);
126
+ }
127
+ }
128
+ // ─────────────────────────────────────────────────────────────────
129
+ // STATE GETTERS
130
+ // ─────────────────────────────────────────────────────────────────
131
+ /** Current lifecycle state */
132
+ get state() { return this._state; }
133
+ /** Whether the process is still running */
134
+ get isRunning() { return this._state === 'running'; }
135
+ // ─────────────────────────────────────────────────────────────────
136
+ // MODE SETUP
137
+ // ─────────────────────────────────────────────────────────────────
138
+ setupPipedMode(proc) {
139
+ if (proc.stdout) {
140
+ proc.stdout.on('data', (chunk) => {
141
+ const str = chunk.toString('utf-8');
142
+ this.appendOutput('stdout', str);
143
+ this.emit('stdout', str);
144
+ });
145
+ }
146
+ if (proc.stderr) {
147
+ proc.stderr.on('data', (chunk) => {
148
+ const str = chunk.toString('utf-8');
149
+ this.appendOutput('stderr', str);
150
+ this.emit('stderr', str);
151
+ });
152
+ }
153
+ }
154
+ setupBridgeMode(proc, _options) {
155
+ if (!proc.stdin || !proc.stdout) {
156
+ throw new KadiError('Failed to get stdio streams for bridge mode', 'PROCESS_BRIDGE_ERROR', { processId: this.id });
157
+ }
158
+ this._reader = new StdioMessageReader(proc.stdout);
159
+ this._writer = new StdioMessageWriter(proc.stdin);
160
+ // Route notifications to event emitter
161
+ this._reader.setNotificationHandler((notification) => {
162
+ this.emit('notification', notification.method, notification.params);
163
+ });
164
+ // Also capture stderr for debugging
165
+ if (proc.stderr) {
166
+ proc.stderr.on('data', (chunk) => {
167
+ const str = chunk.toString('utf-8');
168
+ this.appendOutput('stderr', str);
169
+ this.emit('stderr', str);
170
+ });
171
+ }
172
+ }
173
+ // ─────────────────────────────────────────────────────────────────
174
+ // OUTPUT BUFFERING
175
+ // ─────────────────────────────────────────────────────────────────
176
+ appendOutput(stream, data) {
177
+ if (stream === 'stdout') {
178
+ this._stdout += data;
179
+ if (this._stdout.length > this._maxOutputBuffer) {
180
+ // Ring buffer: keep the most recent data
181
+ this._stdout = this._stdout.slice(-this._maxOutputBuffer);
182
+ }
183
+ }
184
+ else {
185
+ this._stderr += data;
186
+ if (this._stderr.length > this._maxOutputBuffer) {
187
+ this._stderr = this._stderr.slice(-this._maxOutputBuffer);
188
+ }
189
+ }
190
+ }
191
+ /**
192
+ * Get all buffered output.
193
+ * Only available in piped and bridge modes.
194
+ */
195
+ getOutput() {
196
+ return { stdout: this._stdout, stderr: this._stderr };
197
+ }
198
+ // ─────────────────────────────────────────────────────────────────
199
+ // BRIDGE MODE API
200
+ // ─────────────────────────────────────────────────────────────────
201
+ /**
202
+ * Send a JSON-RPC request and await the response.
203
+ * Only available in bridge mode.
204
+ *
205
+ * @param method - The RPC method to invoke
206
+ * @param params - Parameters to send
207
+ * @param timeout - Timeout in ms (default: 600000)
208
+ * @returns The result from the response
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * const result = await proc.request('run-inference', { prompt: 'hello' });
213
+ * ```
214
+ */
215
+ async request(method, params, timeout) {
216
+ if (this.mode !== 'bridge') {
217
+ throw new KadiError('request() is only available in bridge mode', 'PROCESS_BRIDGE_ERROR', { processId: this.id, mode: this.mode });
218
+ }
219
+ if (!this.isRunning) {
220
+ throw new KadiError(`Process "${this.id}" is not running (state: ${this._state})`, 'PROCESS_NOT_RUNNING', { processId: this.id, state: this._state });
221
+ }
222
+ if (!this._reader || !this._writer) {
223
+ throw new KadiError('Bridge streams not initialized', 'PROCESS_BRIDGE_ERROR', { processId: this.id });
224
+ }
225
+ const id = this._bridgeIdCounter++;
226
+ const request = protocol.request(id, method, params ?? {});
227
+ this._writer.write(request);
228
+ const response = await this._reader.waitForResponse(id, timeout);
229
+ if (response.error) {
230
+ throw new KadiError(response.error.message, 'PROCESS_BRIDGE_ERROR', { processId: this.id, code: response.error.code, data: response.error.data });
231
+ }
232
+ return response.result;
233
+ }
234
+ /**
235
+ * Send a JSON-RPC notification (no response expected).
236
+ * Only available in bridge mode.
237
+ */
238
+ notify(method, params) {
239
+ if (this.mode !== 'bridge') {
240
+ throw new KadiError('notify() is only available in bridge mode', 'PROCESS_BRIDGE_ERROR', { processId: this.id, mode: this.mode });
241
+ }
242
+ if (!this.isRunning || !this._writer) {
243
+ throw new KadiError(`Process "${this.id}" is not running`, 'PROCESS_NOT_RUNNING', { processId: this.id });
244
+ }
245
+ // Notifications have no id
246
+ const notification = {
247
+ jsonrpc: '2.0',
248
+ method,
249
+ params: params ?? {},
250
+ };
251
+ const json = JSON.stringify(notification);
252
+ const contentLength = Buffer.byteLength(json, 'utf-8');
253
+ const header = `Content-Length: ${contentLength}\r\n\r\n`;
254
+ this._proc.stdin.write(header + json);
255
+ }
256
+ /**
257
+ * Write raw data to the process stdin.
258
+ * Available in piped and bridge modes.
259
+ */
260
+ write(data) {
261
+ if (this.mode === 'headless') {
262
+ throw new KadiError('write() is not available in headless mode', 'PROCESS_BRIDGE_ERROR', { processId: this.id });
263
+ }
264
+ if (!this.isRunning || !this._proc.stdin) {
265
+ throw new KadiError(`Process "${this.id}" is not running`, 'PROCESS_NOT_RUNNING', { processId: this.id });
266
+ }
267
+ this._proc.stdin.write(data);
268
+ }
269
+ // ─────────────────────────────────────────────────────────────────
270
+ // LIFECYCLE
271
+ // ─────────────────────────────────────────────────────────────────
272
+ /**
273
+ * Kill this process.
274
+ * Sends SIGTERM, waits for grace period, then SIGKILL.
275
+ */
276
+ async kill(signal = 'SIGTERM') {
277
+ if (!this.isRunning)
278
+ return;
279
+ this._proc.kill(signal);
280
+ await new Promise((resolve) => {
281
+ const forceKillTimer = setTimeout(() => {
282
+ if (this.isRunning) {
283
+ this._proc.kill('SIGKILL');
284
+ }
285
+ resolve();
286
+ }, this._killGracePeriod);
287
+ this._proc.once('exit', () => {
288
+ clearTimeout(forceKillTimer);
289
+ resolve();
290
+ });
291
+ });
292
+ }
293
+ /**
294
+ * Wait for the process to exit.
295
+ * Resolves immediately if already exited.
296
+ */
297
+ waitForExit() {
298
+ if (!this.isRunning) {
299
+ return Promise.resolve({
300
+ exitCode: this._exitCode,
301
+ signal: this._signal,
302
+ duration: this._endedAt
303
+ ? this._endedAt.getTime() - this._startedAt.getTime()
304
+ : 0,
305
+ });
306
+ }
307
+ return new Promise((resolve) => {
308
+ this._exitWaiters.push({ resolve });
309
+ });
310
+ }
311
+ /**
312
+ * Get a snapshot of this process's info.
313
+ */
314
+ getInfo() {
315
+ const endedAt = this._endedAt;
316
+ return {
317
+ id: this.id,
318
+ pid: this.pid,
319
+ state: this._state,
320
+ mode: this.mode,
321
+ startedAt: this._startedAt,
322
+ endedAt,
323
+ exitCode: this._exitCode,
324
+ signal: this._signal,
325
+ duration: endedAt
326
+ ? endedAt.getTime() - this._startedAt.getTime()
327
+ : null,
328
+ command: this._command,
329
+ args: this._args,
330
+ cwd: this._cwd,
331
+ };
332
+ }
333
+ // ─────────────────────────────────────────────────────────────────
334
+ // INTERNAL: EXIT HANDLING
335
+ // ─────────────────────────────────────────────────────────────────
336
+ handleExit(code, signal) {
337
+ if (this._timeoutTimer) {
338
+ clearTimeout(this._timeoutTimer);
339
+ this._timeoutTimer = null;
340
+ }
341
+ this._exitCode = code;
342
+ this._signal = signal;
343
+ this._endedAt = new Date();
344
+ if (this._state === 'running') {
345
+ this._state = signal ? 'killed' : 'exited';
346
+ }
347
+ // Cancel any pending bridge requests
348
+ if (this._reader) {
349
+ this._reader.cancelAll(new KadiError('Process exited', 'PROCESS_NOT_RUNNING', { processId: this.id }));
350
+ }
351
+ const exitInfo = {
352
+ exitCode: code,
353
+ signal,
354
+ duration: this._endedAt.getTime() - this._startedAt.getTime(),
355
+ };
356
+ this.emit('exit', exitInfo);
357
+ this.resolveExitWaiters();
358
+ }
359
+ resolveExitWaiters() {
360
+ const info = {
361
+ exitCode: this._exitCode,
362
+ signal: this._signal,
363
+ duration: this._endedAt
364
+ ? this._endedAt.getTime() - this._startedAt.getTime()
365
+ : 0,
366
+ };
367
+ for (const waiter of this._exitWaiters) {
368
+ waiter.resolve(info);
369
+ }
370
+ this._exitWaiters.length = 0;
371
+ }
372
+ }
373
+ // ═══════════════════════════════════════════════════════════════════════
374
+ // PROCESS MANAGER
375
+ // ═══════════════════════════════════════════════════════════════════════
376
+ /**
377
+ * Manages background child processes.
378
+ *
379
+ * Provides spawn, status, kill, and lifecycle management across
380
+ * headless, piped, and bridge execution modes.
381
+ */
382
+ export class ProcessManager {
383
+ /** Active and recently exited processes */
384
+ processes = new Map();
385
+ /** Cleanup handler registered with process.on('exit') */
386
+ cleanupRegistered = false;
387
+ constructor() {
388
+ this.registerCleanup();
389
+ }
390
+ // ─────────────────────────────────────────────────────────────────
391
+ // SPAWN
392
+ // ─────────────────────────────────────────────────────────────────
393
+ /**
394
+ * Spawn a new managed background process.
395
+ *
396
+ * @param id - Unique name for this process
397
+ * @param options - Spawn configuration (command, args, mode, etc.)
398
+ * @returns A ManagedProcess handle
399
+ * @throws PROCESS_ALREADY_EXISTS if a running process with this id exists
400
+ * @throws PROCESS_SPAWN_FAILED if the command fails to start
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * const build = await pm.spawn('build', {
405
+ * command: 'docker',
406
+ * args: ['build', '-t', 'my-app', '.'],
407
+ * cwd: '/path/to/project',
408
+ * mode: 'piped',
409
+ * });
410
+ * ```
411
+ */
412
+ async spawn(id, options) {
413
+ // Check for duplicate running process
414
+ const existing = this.processes.get(id);
415
+ if (existing && existing.isRunning) {
416
+ throw new KadiError(`Process "${id}" is already running`, 'PROCESS_ALREADY_EXISTS', {
417
+ processId: id,
418
+ pid: existing.pid,
419
+ hint: `Kill it first with pm.kill("${id}") or use a different name`,
420
+ });
421
+ }
422
+ // Replace dead process entry
423
+ if (existing) {
424
+ this.processes.delete(id);
425
+ }
426
+ // Determine stdio configuration based on mode
427
+ const stdio = this.getStdioConfig(options.mode);
428
+ // Spawn the child process
429
+ let proc;
430
+ try {
431
+ proc = spawn(options.command, options.args ?? [], {
432
+ stdio,
433
+ cwd: options.cwd,
434
+ env: options.env
435
+ ? { ...process.env, ...options.env }
436
+ : undefined,
437
+ detached: options.mode === 'headless', // Detach headless processes
438
+ });
439
+ }
440
+ catch (error) {
441
+ throw new KadiError(`Failed to spawn process "${id}": ${options.command}`, 'PROCESS_SPAWN_FAILED', {
442
+ processId: id,
443
+ command: options.command,
444
+ args: options.args,
445
+ reason: error instanceof Error ? error.message : String(error),
446
+ hint: 'Check that the command exists and is executable',
447
+ });
448
+ }
449
+ // Verify PID was assigned
450
+ if (proc.pid === undefined) {
451
+ throw new KadiError(`Failed to spawn process "${id}": no PID assigned`, 'PROCESS_SPAWN_FAILED', { processId: id, command: options.command });
452
+ }
453
+ // Handle spawn errors (e.g., ENOENT — command not found)
454
+ // This must be set up synchronously before the next tick
455
+ const spawnError = await new Promise((resolve) => {
456
+ proc.once('error', (err) => resolve(err));
457
+ // If no error by next tick, the spawn succeeded
458
+ setImmediate(() => resolve(null));
459
+ });
460
+ if (spawnError) {
461
+ throw new KadiError(`Failed to spawn process "${id}": ${spawnError.message}`, 'PROCESS_SPAWN_FAILED', {
462
+ processId: id,
463
+ command: options.command,
464
+ reason: spawnError.message,
465
+ hint: 'Check that the command exists and is executable',
466
+ });
467
+ }
468
+ // Create and track the managed process
469
+ const managed = new ManagedProcess(id, proc, options);
470
+ this.processes.set(id, managed);
471
+ return managed;
472
+ }
473
+ // ─────────────────────────────────────────────────────────────────
474
+ // STATUS & QUERYING
475
+ // ─────────────────────────────────────────────────────────────────
476
+ /**
477
+ * Get status information for a specific process.
478
+ *
479
+ * @param id - Process identifier
480
+ * @returns ProcessInfo snapshot
481
+ * @throws PROCESS_NOT_FOUND if no process with this id exists
482
+ */
483
+ getStatus(id) {
484
+ const proc = this.processes.get(id);
485
+ if (!proc) {
486
+ throw new KadiError(`Process "${id}" not found`, 'PROCESS_NOT_FOUND', {
487
+ processId: id,
488
+ available: Array.from(this.processes.keys()),
489
+ hint: 'Use pm.list() to see all managed processes',
490
+ });
491
+ }
492
+ return proc.getInfo();
493
+ }
494
+ /**
495
+ * Get the ManagedProcess handle for a specific process.
496
+ * Useful when you need to attach events or call bridge methods.
497
+ *
498
+ * @param id - Process identifier
499
+ * @returns The ManagedProcess instance
500
+ * @throws PROCESS_NOT_FOUND if no process with this id exists
501
+ */
502
+ get(id) {
503
+ const proc = this.processes.get(id);
504
+ if (!proc) {
505
+ throw new KadiError(`Process "${id}" not found`, 'PROCESS_NOT_FOUND', {
506
+ processId: id,
507
+ available: Array.from(this.processes.keys()),
508
+ });
509
+ }
510
+ return proc;
511
+ }
512
+ /**
513
+ * Get buffered output for a process (piped/bridge modes).
514
+ *
515
+ * @param id - Process identifier
516
+ * @returns Buffered stdout and stderr
517
+ */
518
+ getOutput(id) {
519
+ return this.get(id).getOutput();
520
+ }
521
+ /**
522
+ * List all managed processes, optionally filtered by state.
523
+ *
524
+ * @param options - Optional filter criteria
525
+ * @returns Array of ProcessInfo snapshots
526
+ */
527
+ list(options) {
528
+ const results = [];
529
+ for (const proc of this.processes.values()) {
530
+ const info = proc.getInfo();
531
+ if (options?.state && info.state !== options.state)
532
+ continue;
533
+ if (options?.mode && info.mode !== options.mode)
534
+ continue;
535
+ results.push(info);
536
+ }
537
+ return results;
538
+ }
539
+ // ─────────────────────────────────────────────────────────────────
540
+ // LIFECYCLE MANAGEMENT
541
+ // ─────────────────────────────────────────────────────────────────
542
+ /**
543
+ * Wait for a process to exit.
544
+ *
545
+ * @param id - Process identifier
546
+ * @returns Exit information
547
+ */
548
+ async waitFor(id) {
549
+ return this.get(id).waitForExit();
550
+ }
551
+ /**
552
+ * Kill a specific process.
553
+ *
554
+ * @param id - Process identifier
555
+ * @param signal - Signal to send (default: SIGTERM)
556
+ */
557
+ async kill(id, signal) {
558
+ const proc = this.processes.get(id);
559
+ if (!proc) {
560
+ throw new KadiError(`Process "${id}" not found`, 'PROCESS_NOT_FOUND', { processId: id });
561
+ }
562
+ await proc.kill(signal);
563
+ }
564
+ /**
565
+ * Kill all running managed processes.
566
+ */
567
+ async killAll() {
568
+ const kills = [];
569
+ for (const proc of this.processes.values()) {
570
+ if (proc.isRunning) {
571
+ kills.push(proc.kill());
572
+ }
573
+ }
574
+ await Promise.allSettled(kills);
575
+ }
576
+ /**
577
+ * Remove exited/errored/killed processes from tracking.
578
+ *
579
+ * @param options - Optional criteria for which processes to remove
580
+ */
581
+ prune(options) {
582
+ const now = Date.now();
583
+ for (const [id, proc] of this.processes) {
584
+ if (proc.isRunning)
585
+ continue;
586
+ const info = proc.getInfo();
587
+ if (options?.olderThan !== undefined) {
588
+ const endedAt = info.endedAt?.getTime() ?? now;
589
+ const ageSeconds = (now - endedAt) / 1000;
590
+ if (ageSeconds >= options.olderThan) {
591
+ this.processes.delete(id);
592
+ }
593
+ }
594
+ else {
595
+ // No filter — remove all non-running
596
+ this.processes.delete(id);
597
+ }
598
+ }
599
+ }
600
+ /**
601
+ * Graceful shutdown: SIGTERM all running processes, wait, then SIGKILL remainders.
602
+ */
603
+ async shutdown() {
604
+ await this.killAll();
605
+ this.prune();
606
+ }
607
+ // ─────────────────────────────────────────────────────────────────
608
+ // INTERNAL
609
+ // ─────────────────────────────────────────────────────────────────
610
+ /**
611
+ * Determine stdio configuration based on process mode.
612
+ */
613
+ getStdioConfig(mode) {
614
+ switch (mode) {
615
+ case 'headless':
616
+ return ['ignore', 'ignore', 'ignore'];
617
+ case 'piped':
618
+ return ['ignore', 'pipe', 'pipe'];
619
+ case 'bridge':
620
+ return ['pipe', 'pipe', 'pipe'];
621
+ }
622
+ }
623
+ /**
624
+ * Register a cleanup handler to kill child processes when the parent exits.
625
+ */
626
+ registerCleanup() {
627
+ if (this.cleanupRegistered)
628
+ return;
629
+ this.cleanupRegistered = true;
630
+ const cleanup = () => {
631
+ for (const proc of this.processes.values()) {
632
+ if (proc.isRunning) {
633
+ try {
634
+ proc.kill('SIGTERM').catch(() => { });
635
+ }
636
+ catch {
637
+ // Best-effort cleanup
638
+ }
639
+ }
640
+ }
641
+ };
642
+ process.on('exit', cleanup);
643
+ process.on('SIGTERM', cleanup);
644
+ process.on('SIGINT', cleanup);
645
+ }
646
+ }
647
+ //# sourceMappingURL=process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}