@kadi.build/core 0.8.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.
- package/README.md +424 -1
- package/agent.json +19 -0
- package/dist/agent-json.d.ts +231 -0
- package/dist/agent-json.d.ts.map +1 -0
- package/dist/agent-json.js +554 -0
- package/dist/agent-json.js.map +1 -0
- package/dist/client.d.ts +41 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +102 -43
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/process-manager.d.ts +235 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +647 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/stdio-framing.d.ts +88 -0
- package/dist/stdio-framing.d.ts.map +1 -0
- package/dist/stdio-framing.js +194 -0
- package/dist/stdio-framing.js.map +1 -0
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +3 -181
- package/dist/transports/stdio.js.map +1 -1
- package/dist/types.d.ts +274 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +107 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +212 -0
- package/dist/utils.js.map +1 -0
- package/package.json +3 -1
- package/scripts/symlink.mjs +131 -0
- package/src/agent-json.ts +655 -0
- package/src/client.ts +120 -46
- package/src/errors.ts +15 -0
- package/src/index.ts +32 -0
- package/src/process-manager.ts +821 -0
- package/src/stdio-framing.ts +227 -0
- package/src/transports/stdio.ts +4 -221
- package/src/types.ts +291 -23
- package/src/utils.ts +246 -0
|
@@ -0,0 +1,235 @@
|
|
|
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 { type ChildProcess } from 'child_process';
|
|
39
|
+
import { EventEmitter } from 'events';
|
|
40
|
+
import type { ProcessMode, ProcessState, SpawnOptions, ProcessInfo, ProcessExitInfo, ProcessOutput, ProcessListOptions, ProcessPruneOptions } from './types.js';
|
|
41
|
+
/**
|
|
42
|
+
* A handle to a spawned background process.
|
|
43
|
+
*
|
|
44
|
+
* Provides event subscription, lifecycle management, and (in bridge mode)
|
|
45
|
+
* JSON-RPC request/response communication.
|
|
46
|
+
*/
|
|
47
|
+
export declare class ManagedProcess extends EventEmitter {
|
|
48
|
+
/** Unique identifier */
|
|
49
|
+
readonly id: string;
|
|
50
|
+
/** OS process ID */
|
|
51
|
+
readonly pid: number;
|
|
52
|
+
/** Execution mode */
|
|
53
|
+
readonly mode: ProcessMode;
|
|
54
|
+
/** Internal state */
|
|
55
|
+
private _state;
|
|
56
|
+
private _exitCode;
|
|
57
|
+
private _signal;
|
|
58
|
+
private _startedAt;
|
|
59
|
+
private _endedAt;
|
|
60
|
+
/** Command info for getInfo() */
|
|
61
|
+
private readonly _command;
|
|
62
|
+
private readonly _args;
|
|
63
|
+
private readonly _cwd;
|
|
64
|
+
/** Output buffering (piped mode) */
|
|
65
|
+
private _stdout;
|
|
66
|
+
private _stderr;
|
|
67
|
+
private readonly _maxOutputBuffer;
|
|
68
|
+
/** Bridge mode internals */
|
|
69
|
+
private _reader;
|
|
70
|
+
private _writer;
|
|
71
|
+
private _bridgeIdCounter;
|
|
72
|
+
/** The underlying child process */
|
|
73
|
+
private readonly _proc;
|
|
74
|
+
/** Timeout timer for auto-kill */
|
|
75
|
+
private _timeoutTimer;
|
|
76
|
+
/** Kill grace period */
|
|
77
|
+
private readonly _killGracePeriod;
|
|
78
|
+
/** Waiters for the exit event */
|
|
79
|
+
private readonly _exitWaiters;
|
|
80
|
+
constructor(id: string, proc: ChildProcess, options: SpawnOptions);
|
|
81
|
+
/** Current lifecycle state */
|
|
82
|
+
get state(): ProcessState;
|
|
83
|
+
/** Whether the process is still running */
|
|
84
|
+
get isRunning(): boolean;
|
|
85
|
+
private setupPipedMode;
|
|
86
|
+
private setupBridgeMode;
|
|
87
|
+
private appendOutput;
|
|
88
|
+
/**
|
|
89
|
+
* Get all buffered output.
|
|
90
|
+
* Only available in piped and bridge modes.
|
|
91
|
+
*/
|
|
92
|
+
getOutput(): ProcessOutput;
|
|
93
|
+
/**
|
|
94
|
+
* Send a JSON-RPC request and await the response.
|
|
95
|
+
* Only available in bridge mode.
|
|
96
|
+
*
|
|
97
|
+
* @param method - The RPC method to invoke
|
|
98
|
+
* @param params - Parameters to send
|
|
99
|
+
* @param timeout - Timeout in ms (default: 600000)
|
|
100
|
+
* @returns The result from the response
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const result = await proc.request('run-inference', { prompt: 'hello' });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
request(method: string, params?: unknown, timeout?: number): Promise<unknown>;
|
|
108
|
+
/**
|
|
109
|
+
* Send a JSON-RPC notification (no response expected).
|
|
110
|
+
* Only available in bridge mode.
|
|
111
|
+
*/
|
|
112
|
+
notify(method: string, params?: unknown): void;
|
|
113
|
+
/**
|
|
114
|
+
* Write raw data to the process stdin.
|
|
115
|
+
* Available in piped and bridge modes.
|
|
116
|
+
*/
|
|
117
|
+
write(data: string | Buffer): void;
|
|
118
|
+
/**
|
|
119
|
+
* Kill this process.
|
|
120
|
+
* Sends SIGTERM, waits for grace period, then SIGKILL.
|
|
121
|
+
*/
|
|
122
|
+
kill(signal?: NodeJS.Signals): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Wait for the process to exit.
|
|
125
|
+
* Resolves immediately if already exited.
|
|
126
|
+
*/
|
|
127
|
+
waitForExit(): Promise<ProcessExitInfo>;
|
|
128
|
+
/**
|
|
129
|
+
* Get a snapshot of this process's info.
|
|
130
|
+
*/
|
|
131
|
+
getInfo(): ProcessInfo;
|
|
132
|
+
private handleExit;
|
|
133
|
+
private resolveExitWaiters;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Manages background child processes.
|
|
137
|
+
*
|
|
138
|
+
* Provides spawn, status, kill, and lifecycle management across
|
|
139
|
+
* headless, piped, and bridge execution modes.
|
|
140
|
+
*/
|
|
141
|
+
export declare class ProcessManager {
|
|
142
|
+
/** Active and recently exited processes */
|
|
143
|
+
private readonly processes;
|
|
144
|
+
/** Cleanup handler registered with process.on('exit') */
|
|
145
|
+
private cleanupRegistered;
|
|
146
|
+
constructor();
|
|
147
|
+
/**
|
|
148
|
+
* Spawn a new managed background process.
|
|
149
|
+
*
|
|
150
|
+
* @param id - Unique name for this process
|
|
151
|
+
* @param options - Spawn configuration (command, args, mode, etc.)
|
|
152
|
+
* @returns A ManagedProcess handle
|
|
153
|
+
* @throws PROCESS_ALREADY_EXISTS if a running process with this id exists
|
|
154
|
+
* @throws PROCESS_SPAWN_FAILED if the command fails to start
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const build = await pm.spawn('build', {
|
|
159
|
+
* command: 'docker',
|
|
160
|
+
* args: ['build', '-t', 'my-app', '.'],
|
|
161
|
+
* cwd: '/path/to/project',
|
|
162
|
+
* mode: 'piped',
|
|
163
|
+
* });
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
spawn(id: string, options: SpawnOptions): Promise<ManagedProcess>;
|
|
167
|
+
/**
|
|
168
|
+
* Get status information for a specific process.
|
|
169
|
+
*
|
|
170
|
+
* @param id - Process identifier
|
|
171
|
+
* @returns ProcessInfo snapshot
|
|
172
|
+
* @throws PROCESS_NOT_FOUND if no process with this id exists
|
|
173
|
+
*/
|
|
174
|
+
getStatus(id: string): ProcessInfo;
|
|
175
|
+
/**
|
|
176
|
+
* Get the ManagedProcess handle for a specific process.
|
|
177
|
+
* Useful when you need to attach events or call bridge methods.
|
|
178
|
+
*
|
|
179
|
+
* @param id - Process identifier
|
|
180
|
+
* @returns The ManagedProcess instance
|
|
181
|
+
* @throws PROCESS_NOT_FOUND if no process with this id exists
|
|
182
|
+
*/
|
|
183
|
+
get(id: string): ManagedProcess;
|
|
184
|
+
/**
|
|
185
|
+
* Get buffered output for a process (piped/bridge modes).
|
|
186
|
+
*
|
|
187
|
+
* @param id - Process identifier
|
|
188
|
+
* @returns Buffered stdout and stderr
|
|
189
|
+
*/
|
|
190
|
+
getOutput(id: string): ProcessOutput;
|
|
191
|
+
/**
|
|
192
|
+
* List all managed processes, optionally filtered by state.
|
|
193
|
+
*
|
|
194
|
+
* @param options - Optional filter criteria
|
|
195
|
+
* @returns Array of ProcessInfo snapshots
|
|
196
|
+
*/
|
|
197
|
+
list(options?: ProcessListOptions): ProcessInfo[];
|
|
198
|
+
/**
|
|
199
|
+
* Wait for a process to exit.
|
|
200
|
+
*
|
|
201
|
+
* @param id - Process identifier
|
|
202
|
+
* @returns Exit information
|
|
203
|
+
*/
|
|
204
|
+
waitFor(id: string): Promise<ProcessExitInfo>;
|
|
205
|
+
/**
|
|
206
|
+
* Kill a specific process.
|
|
207
|
+
*
|
|
208
|
+
* @param id - Process identifier
|
|
209
|
+
* @param signal - Signal to send (default: SIGTERM)
|
|
210
|
+
*/
|
|
211
|
+
kill(id: string, signal?: NodeJS.Signals): Promise<void>;
|
|
212
|
+
/**
|
|
213
|
+
* Kill all running managed processes.
|
|
214
|
+
*/
|
|
215
|
+
killAll(): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* Remove exited/errored/killed processes from tracking.
|
|
218
|
+
*
|
|
219
|
+
* @param options - Optional criteria for which processes to remove
|
|
220
|
+
*/
|
|
221
|
+
prune(options?: ProcessPruneOptions): void;
|
|
222
|
+
/**
|
|
223
|
+
* Graceful shutdown: SIGTERM all running processes, wait, then SIGKILL remainders.
|
|
224
|
+
*/
|
|
225
|
+
shutdown(): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Determine stdio configuration based on process mode.
|
|
228
|
+
*/
|
|
229
|
+
private getStdioConfig;
|
|
230
|
+
/**
|
|
231
|
+
* Register a cleanup handler to kill child processes when the parent exits.
|
|
232
|
+
*/
|
|
233
|
+
private registerCleanup;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=process-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}
|