pi-kot 0.1.39 → 0.1.40
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/dist/client/assets/index-DH1DarDy.js +196 -0
- package/dist/client/assets/index-DH1DarDy.js.map +1 -0
- package/dist/client/assets/index-DYWeNL-y.css +1 -0
- package/dist/client/assets/vendor-icons-BpFAkgBQ.js +2 -0
- package/dist/client/assets/vendor-icons-BpFAkgBQ.js.map +1 -0
- package/dist/client/assets/{vendor-markdown-DUXj0nma.js → vendor-markdown-BDlxJt__.js} +2 -2
- package/dist/client/assets/{vendor-markdown-DUXj0nma.js.map → vendor-markdown-BDlxJt__.js.map} +1 -1
- package/dist/client/assets/vendor-prism-CNIrsK0M.js +4 -0
- package/dist/client/assets/{vendor-prism-tzddbd4Y.js.map → vendor-prism-CNIrsK0M.js.map} +1 -1
- package/dist/client/index.html +5 -5
- package/dist/server/archive-retention.test.d.ts +2 -0
- package/dist/server/archive-retention.test.d.ts.map +1 -0
- package/dist/server/archive-retention.test.js +63 -0
- package/dist/server/archive-retention.test.js.map +1 -0
- package/dist/server/contexts/web-ui.md +12 -3
- package/dist/server/event-stream.d.ts.map +1 -1
- package/dist/server/event-stream.js +14 -0
- package/dist/server/event-stream.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +88 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/processes/envelope.d.ts +5 -0
- package/dist/server/processes/envelope.d.ts.map +1 -0
- package/dist/server/processes/envelope.js +29 -0
- package/dist/server/processes/envelope.js.map +1 -0
- package/dist/server/processes/log-store.d.ts +24 -0
- package/dist/server/processes/log-store.d.ts.map +1 -0
- package/dist/server/processes/log-store.js +86 -0
- package/dist/server/processes/log-store.js.map +1 -0
- package/dist/server/processes/manager.d.ts +56 -0
- package/dist/server/processes/manager.d.ts.map +1 -0
- package/dist/server/processes/manager.js +343 -0
- package/dist/server/processes/manager.js.map +1 -0
- package/dist/server/processes/processes.test.d.ts +2 -0
- package/dist/server/processes/processes.test.d.ts.map +1 -0
- package/dist/server/processes/processes.test.js +85 -0
- package/dist/server/processes/processes.test.js.map +1 -0
- package/dist/server/processes/prompt-strings.d.ts +7 -0
- package/dist/server/processes/prompt-strings.d.ts.map +1 -0
- package/dist/server/processes/prompt-strings.js +28 -0
- package/dist/server/processes/prompt-strings.js.map +1 -0
- package/dist/server/processes/tool.d.ts +3 -0
- package/dist/server/processes/tool.d.ts.map +1 -0
- package/dist/server/processes/tool.js +160 -0
- package/dist/server/processes/tool.js.map +1 -0
- package/dist/server/processes/types.d.ts +125 -0
- package/dist/server/processes/types.d.ts.map +1 -0
- package/dist/server/processes/types.js +13 -0
- package/dist/server/processes/types.js.map +1 -0
- package/dist/server/processes/watches.d.ts +13 -0
- package/dist/server/processes/watches.d.ts.map +1 -0
- package/dist/server/processes/watches.js +55 -0
- package/dist/server/processes/watches.js.map +1 -0
- package/dist/server/routes/config.js +2 -2
- package/dist/server/routes/config.js.map +1 -1
- package/dist/server/routes/files-batch-delete.test.d.ts +2 -0
- package/dist/server/routes/files-batch-delete.test.d.ts.map +1 -0
- package/dist/server/routes/files-batch-delete.test.js +165 -0
- package/dist/server/routes/files-batch-delete.test.js.map +1 -0
- package/dist/server/routes/files.d.ts.map +1 -1
- package/dist/server/routes/files.js +99 -0
- package/dist/server/routes/files.js.map +1 -1
- package/dist/server/routes/processes.d.ts +3 -0
- package/dist/server/routes/processes.d.ts.map +1 -0
- package/dist/server/routes/processes.js +63 -0
- package/dist/server/routes/processes.js.map +1 -0
- package/dist/server/routes/sessions.d.ts.map +1 -1
- package/dist/server/routes/sessions.js +30 -1
- package/dist/server/routes/sessions.js.map +1 -1
- package/dist/server/session-store.d.ts +15 -1
- package/dist/server/session-store.d.ts.map +1 -1
- package/dist/server/session-store.js +99 -4
- package/dist/server/session-store.js.map +1 -1
- package/dist/server/ui-settings-store.d.ts +3 -0
- package/dist/server/ui-settings-store.d.ts.map +1 -1
- package/dist/server/ui-settings-store.js +11 -1
- package/dist/server/ui-settings-store.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/index-B959AkDe.css +0 -1
- package/dist/client/assets/index-BH5vWV2p.js +0 -192
- package/dist/client/assets/index-BH5vWV2p.js.map +0 -1
- package/dist/client/assets/vendor-icons-xTgSApeH.js +0 -2
- package/dist/client/assets/vendor-icons-xTgSApeH.js.map +0 -1
- package/dist/client/assets/vendor-prism-tzddbd4Y.js +0 -4
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { config } from "../config.js";
|
|
5
|
+
import { LogChannel, processLogDir } from "./log-store.js";
|
|
6
|
+
import { buildMatchEvent, compileWatches, evaluateWatches } from "./watches.js";
|
|
7
|
+
import { LIVE_STATUSES, } from "./types.js";
|
|
8
|
+
const GRACE_MS = 5_000;
|
|
9
|
+
const SIGKILL_TIMEOUT_MS = 2_000;
|
|
10
|
+
function sanitizeEnvironment(extra = {}) {
|
|
11
|
+
const env = { ...process.env, ...extra };
|
|
12
|
+
// Clean sensitive server credentials from child process environment
|
|
13
|
+
delete env.API_KEY;
|
|
14
|
+
delete env.UI_PASSWORD;
|
|
15
|
+
delete env.JWT_SECRET;
|
|
16
|
+
return env;
|
|
17
|
+
}
|
|
18
|
+
export class ProcessManager {
|
|
19
|
+
bySession = new Map();
|
|
20
|
+
listeners = new Set();
|
|
21
|
+
subscribe(fn) {
|
|
22
|
+
this.listeners.add(fn);
|
|
23
|
+
return () => {
|
|
24
|
+
this.listeners.delete(fn);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
notify(event) {
|
|
28
|
+
for (const fn of this.listeners) {
|
|
29
|
+
try {
|
|
30
|
+
fn(event);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Listener errors must not crash manager
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
getOrCreateSession(sessionId) {
|
|
38
|
+
let s = this.bySession.get(sessionId);
|
|
39
|
+
if (s === undefined) {
|
|
40
|
+
s = { sessionId, processes: new Map() };
|
|
41
|
+
this.bySession.set(sessionId, s);
|
|
42
|
+
}
|
|
43
|
+
return s;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Spawn a new background process bound to a session.
|
|
47
|
+
*/
|
|
48
|
+
start(sessionId, name, command, cwd, opts = {}) {
|
|
49
|
+
const session = this.getOrCreateSession(sessionId);
|
|
50
|
+
const id = randomBytes(4).toString("hex");
|
|
51
|
+
const logDir = processLogDir(config.forgeDataDir, sessionId, id);
|
|
52
|
+
const stdoutFile = join(logDir, "stdout.log");
|
|
53
|
+
const stderrFile = join(logDir, "stderr.log");
|
|
54
|
+
// Spawn under `/bin/sh -c` with detached: true so kill(-pid) kills the whole process group
|
|
55
|
+
const child = spawn("/bin/sh", ["-c", command], {
|
|
56
|
+
cwd,
|
|
57
|
+
env: sanitizeEnvironment(opts.toolEnv),
|
|
58
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
59
|
+
detached: true,
|
|
60
|
+
});
|
|
61
|
+
const info = {
|
|
62
|
+
id,
|
|
63
|
+
name,
|
|
64
|
+
pid: child.pid ?? -1,
|
|
65
|
+
command,
|
|
66
|
+
cwd,
|
|
67
|
+
startTime: Date.now(),
|
|
68
|
+
endTime: null,
|
|
69
|
+
status: "running",
|
|
70
|
+
exitCode: null,
|
|
71
|
+
success: null,
|
|
72
|
+
stdoutFile,
|
|
73
|
+
stderrFile,
|
|
74
|
+
alertOnSuccess: opts.alertOnSuccess === true,
|
|
75
|
+
alertOnFailure: opts.alertOnFailure !== false, // default true
|
|
76
|
+
alertOnKill: opts.alertOnKill === true,
|
|
77
|
+
};
|
|
78
|
+
const managed = {
|
|
79
|
+
info,
|
|
80
|
+
child,
|
|
81
|
+
stdout: new LogChannel(stdoutFile),
|
|
82
|
+
stderr: new LogChannel(stderrFile),
|
|
83
|
+
watches: compileWatches(opts.logWatches),
|
|
84
|
+
killSent: null,
|
|
85
|
+
killTimer: null,
|
|
86
|
+
};
|
|
87
|
+
session.processes.set(id, managed);
|
|
88
|
+
const wireUp = (source) => {
|
|
89
|
+
const stream = source === "stdout" ? child.stdout : child.stderr;
|
|
90
|
+
const channel = source === "stdout" ? managed.stdout : managed.stderr;
|
|
91
|
+
stream.on("data", (chunk) => {
|
|
92
|
+
channel.append(chunk, (line) => {
|
|
93
|
+
const hits = evaluateWatches(managed.watches, source, line);
|
|
94
|
+
for (const w of hits) {
|
|
95
|
+
this.notify({
|
|
96
|
+
type: "process_watch_matched",
|
|
97
|
+
sessionId,
|
|
98
|
+
match: buildMatchEvent(w, id, name, command, source, line),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
this.notify({ type: "process_output_changed", sessionId, id });
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
wireUp("stdout");
|
|
106
|
+
wireUp("stderr");
|
|
107
|
+
child.on("error", (err) => {
|
|
108
|
+
const text = `[spawn error] ${err.message}\n`;
|
|
109
|
+
managed.stderr.append(Buffer.from(text, "utf8"));
|
|
110
|
+
info.endTime = Date.now();
|
|
111
|
+
info.exitCode = -1;
|
|
112
|
+
info.success = false;
|
|
113
|
+
info.status = "exited";
|
|
114
|
+
this.notify({ type: "process_ended", sessionId, info });
|
|
115
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
116
|
+
if (info.alertOnFailure) {
|
|
117
|
+
this.notify({
|
|
118
|
+
type: "process_alert",
|
|
119
|
+
sessionId,
|
|
120
|
+
info,
|
|
121
|
+
reason: "failure",
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
void this.finalize(managed);
|
|
125
|
+
});
|
|
126
|
+
child.on("close", (code, signal) => {
|
|
127
|
+
info.endTime = Date.now();
|
|
128
|
+
info.exitCode = typeof code === "number" ? code : null;
|
|
129
|
+
const killedByUs = managed.killSent !== null;
|
|
130
|
+
const killedExternally = !killedByUs && signal !== null;
|
|
131
|
+
const wasKilled = killedByUs || killedExternally;
|
|
132
|
+
info.status = wasKilled ? "killed" : "exited";
|
|
133
|
+
info.success = info.exitCode === 0 && !wasKilled;
|
|
134
|
+
if (managed.killTimer !== null) {
|
|
135
|
+
clearTimeout(managed.killTimer);
|
|
136
|
+
managed.killTimer = null;
|
|
137
|
+
}
|
|
138
|
+
this.notify({ type: "process_ended", sessionId, info });
|
|
139
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
140
|
+
// Determine alert notifications
|
|
141
|
+
if (info.success && info.alertOnSuccess) {
|
|
142
|
+
this.notify({
|
|
143
|
+
type: "process_alert",
|
|
144
|
+
sessionId,
|
|
145
|
+
info,
|
|
146
|
+
reason: "success",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else if (!info.success && !wasKilled && info.alertOnFailure) {
|
|
150
|
+
this.notify({
|
|
151
|
+
type: "process_alert",
|
|
152
|
+
sessionId,
|
|
153
|
+
info,
|
|
154
|
+
reason: "failure",
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else if (killedExternally && info.alertOnKill) {
|
|
158
|
+
this.notify({
|
|
159
|
+
type: "process_alert",
|
|
160
|
+
sessionId,
|
|
161
|
+
info,
|
|
162
|
+
reason: "killed",
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
void this.finalize(managed);
|
|
166
|
+
});
|
|
167
|
+
this.notify({ type: "process_started", sessionId, info });
|
|
168
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
169
|
+
return info;
|
|
170
|
+
}
|
|
171
|
+
async finalize(managed) {
|
|
172
|
+
try {
|
|
173
|
+
await Promise.all([managed.stdout.close(), managed.stderr.close()]);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// best-effort
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* List all processes for a session.
|
|
181
|
+
*/
|
|
182
|
+
list(sessionId) {
|
|
183
|
+
const session = this.bySession.get(sessionId);
|
|
184
|
+
if (!session)
|
|
185
|
+
return [];
|
|
186
|
+
return Array.from(session.processes.values())
|
|
187
|
+
.map((m) => ({ ...m.info }))
|
|
188
|
+
.sort((a, b) => b.startTime - a.startTime);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get a single process info by ID.
|
|
192
|
+
*/
|
|
193
|
+
get(sessionId, id) {
|
|
194
|
+
return this.bySession.get(sessionId)?.processes.get(id)?.info;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get recent stdout/stderr output lines for a process.
|
|
198
|
+
*/
|
|
199
|
+
getOutput(sessionId, id, lineCount = 200) {
|
|
200
|
+
const managed = this.bySession.get(sessionId)?.processes.get(id);
|
|
201
|
+
if (!managed)
|
|
202
|
+
return undefined;
|
|
203
|
+
return {
|
|
204
|
+
stdout: managed.stdout.tail(lineCount),
|
|
205
|
+
stderr: managed.stderr.tail(lineCount),
|
|
206
|
+
status: managed.info.status,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get on-disk log file paths for a process.
|
|
211
|
+
*/
|
|
212
|
+
getLogFiles(sessionId, id) {
|
|
213
|
+
const managed = this.bySession.get(sessionId)?.processes.get(id);
|
|
214
|
+
if (!managed)
|
|
215
|
+
return undefined;
|
|
216
|
+
return {
|
|
217
|
+
stdoutFile: managed.info.stdoutFile,
|
|
218
|
+
stderrFile: managed.info.stderrFile,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Terminate a process: SIGTERM -> wait GRACE_MS -> SIGKILL.
|
|
223
|
+
*/
|
|
224
|
+
async kill(sessionId, id) {
|
|
225
|
+
const managed = this.bySession.get(sessionId)?.processes.get(id);
|
|
226
|
+
if (!managed)
|
|
227
|
+
return { ok: false, info: undefined, reason: "not_found" };
|
|
228
|
+
if (!LIVE_STATUSES.has(managed.info.status)) {
|
|
229
|
+
return { ok: true, info: managed.info };
|
|
230
|
+
}
|
|
231
|
+
managed.info.status = "terminating";
|
|
232
|
+
managed.killSent = "SIGTERM";
|
|
233
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
234
|
+
const sendSignal = (sig) => {
|
|
235
|
+
const pid = managed.child.pid;
|
|
236
|
+
if (pid === undefined)
|
|
237
|
+
return;
|
|
238
|
+
try {
|
|
239
|
+
// Signal the whole process group (detached process)
|
|
240
|
+
process.kill(-pid, sig);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
try {
|
|
244
|
+
managed.child.kill(sig);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// already exited
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
sendSignal("SIGTERM");
|
|
252
|
+
return new Promise((resolve) => {
|
|
253
|
+
let resolved = false;
|
|
254
|
+
const finish = (result) => {
|
|
255
|
+
if (resolved)
|
|
256
|
+
return;
|
|
257
|
+
resolved = true;
|
|
258
|
+
if (managed.killTimer !== null) {
|
|
259
|
+
clearTimeout(managed.killTimer);
|
|
260
|
+
managed.killTimer = null;
|
|
261
|
+
}
|
|
262
|
+
resolve(result);
|
|
263
|
+
};
|
|
264
|
+
managed.child.once("close", () => {
|
|
265
|
+
finish({ ok: true, info: managed.info });
|
|
266
|
+
});
|
|
267
|
+
managed.killTimer = setTimeout(() => {
|
|
268
|
+
if (!LIVE_STATUSES.has(managed.info.status))
|
|
269
|
+
return;
|
|
270
|
+
managed.info.status = "terminate_timeout";
|
|
271
|
+
managed.killSent = "SIGKILL";
|
|
272
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
273
|
+
sendSignal("SIGKILL");
|
|
274
|
+
managed.killTimer = setTimeout(() => {
|
|
275
|
+
finish({ ok: false, info: managed.info, reason: "timeout" });
|
|
276
|
+
}, SIGKILL_TIMEOUT_MS);
|
|
277
|
+
}, GRACE_MS);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Write to process stdin.
|
|
282
|
+
*/
|
|
283
|
+
write(sessionId, id, input, end = false) {
|
|
284
|
+
const managed = this.bySession.get(sessionId)?.processes.get(id);
|
|
285
|
+
if (!managed)
|
|
286
|
+
return { ok: false, reason: "not_found" };
|
|
287
|
+
if (!LIVE_STATUSES.has(managed.info.status)) {
|
|
288
|
+
return { ok: false, reason: "process_exited" };
|
|
289
|
+
}
|
|
290
|
+
const stdin = managed.child.stdin;
|
|
291
|
+
if (!stdin || stdin.destroyed || stdin.writableEnded) {
|
|
292
|
+
return { ok: false, reason: "stdin_closed" };
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
stdin.write(input);
|
|
296
|
+
if (end)
|
|
297
|
+
stdin.end();
|
|
298
|
+
return { ok: true };
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return { ok: false, reason: "write_error" };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Remove finished / exited / killed processes from the session state.
|
|
306
|
+
*/
|
|
307
|
+
clearFinished(sessionId) {
|
|
308
|
+
const session = this.bySession.get(sessionId);
|
|
309
|
+
if (!session)
|
|
310
|
+
return 0;
|
|
311
|
+
let cleared = 0;
|
|
312
|
+
for (const [id, proc] of session.processes.entries()) {
|
|
313
|
+
if (!LIVE_STATUSES.has(proc.info.status)) {
|
|
314
|
+
session.processes.delete(id);
|
|
315
|
+
cleared++;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (cleared > 0) {
|
|
319
|
+
this.notify({ type: "processes_changed", sessionId });
|
|
320
|
+
}
|
|
321
|
+
return cleared;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Kill all processes and clean up when a session is disposed.
|
|
325
|
+
*/
|
|
326
|
+
async disposeSession(sessionId) {
|
|
327
|
+
const session = this.bySession.get(sessionId);
|
|
328
|
+
if (!session)
|
|
329
|
+
return;
|
|
330
|
+
const liveProcesses = Array.from(session.processes.values()).filter((p) => LIVE_STATUSES.has(p.info.status));
|
|
331
|
+
await Promise.all(liveProcesses.map(async (proc) => {
|
|
332
|
+
try {
|
|
333
|
+
await this.kill(sessionId, proc.info.id);
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// best-effort cleanup
|
|
337
|
+
}
|
|
338
|
+
}));
|
|
339
|
+
this.bySession.delete(sessionId);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
export const processManager = new ProcessManager();
|
|
343
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/processes/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processes.test.d.ts","sourceRoot":"","sources":["../../src/processes/processes.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { processManager } from "./manager.js";
|
|
3
|
+
import { createProcessTool } from "./tool.js";
|
|
4
|
+
const TEST_SESSION = "test-session-" + Date.now();
|
|
5
|
+
describe("Background Process Manager", () => {
|
|
6
|
+
afterEach(async () => {
|
|
7
|
+
await processManager.disposeSession(TEST_SESSION);
|
|
8
|
+
});
|
|
9
|
+
it("starts, lists, and kills a process", async () => {
|
|
10
|
+
const info = processManager.start(TEST_SESSION, "test-echo", "node -e 'setInterval(() => console.log(\"hello\"), 100)'", process.cwd());
|
|
11
|
+
expect(info.id).toBeDefined();
|
|
12
|
+
expect(info.status).toBe("running");
|
|
13
|
+
expect(info.pid).toBeGreaterThan(0);
|
|
14
|
+
const list = processManager.list(TEST_SESSION);
|
|
15
|
+
expect(list.length).toBe(1);
|
|
16
|
+
expect(list[0].id).toBe(info.id);
|
|
17
|
+
// Wait a brief moment for output
|
|
18
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
19
|
+
const out = processManager.getOutput(TEST_SESSION, info.id);
|
|
20
|
+
expect(out).toBeDefined();
|
|
21
|
+
expect(out?.stdout.some((line) => line.includes("hello"))).toBe(true);
|
|
22
|
+
const killRes = await processManager.kill(TEST_SESSION, info.id);
|
|
23
|
+
expect(killRes.ok).toBe(true);
|
|
24
|
+
// After kill, status should update to killed or exited
|
|
25
|
+
const updated = processManager.get(TEST_SESSION, info.id);
|
|
26
|
+
expect(["killed", "exited"]).toContain(updated?.status);
|
|
27
|
+
});
|
|
28
|
+
it("writes to stdin and receives response", async () => {
|
|
29
|
+
const info = processManager.start(TEST_SESSION, "test-stdin", "node -e 'process.stdin.on(\"data\", d => console.log(\"echo:\" + d.toString().trim()))'", process.cwd());
|
|
30
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
31
|
+
const writeRes = processManager.write(TEST_SESSION, info.id, "pi-kot\n");
|
|
32
|
+
expect(writeRes.ok).toBe(true);
|
|
33
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
34
|
+
const out = processManager.getOutput(TEST_SESSION, info.id);
|
|
35
|
+
expect(out?.stdout.some((line) => line.includes("echo:pi-kot"))).toBe(true);
|
|
36
|
+
await processManager.kill(TEST_SESSION, info.id);
|
|
37
|
+
});
|
|
38
|
+
it("triggers logWatches regex matches", async () => {
|
|
39
|
+
const matchedLines = [];
|
|
40
|
+
const unsubscribe = processManager.subscribe((ev) => {
|
|
41
|
+
if (ev.type === "process_watch_matched") {
|
|
42
|
+
matchedLines.push(ev.match.line);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const info = processManager.start(TEST_SESSION, "test-watch", "node -e 'console.log(\"READY: server started\"); setInterval(() => {}, 100)'", process.cwd(), {
|
|
46
|
+
logWatches: [{ pattern: "READY: .*" }],
|
|
47
|
+
});
|
|
48
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
49
|
+
expect(matchedLines.length).toBeGreaterThanOrEqual(1);
|
|
50
|
+
expect(matchedLines[0]).toContain("READY: server started");
|
|
51
|
+
unsubscribe();
|
|
52
|
+
await processManager.kill(TEST_SESSION, info.id);
|
|
53
|
+
});
|
|
54
|
+
it("clears finished processes", async () => {
|
|
55
|
+
const info = processManager.start(TEST_SESSION, "quick-exit", "node -e 'process.exit(0)'", process.cwd());
|
|
56
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
57
|
+
const cleared = processManager.clearFinished(TEST_SESSION);
|
|
58
|
+
expect(cleared).toBe(1);
|
|
59
|
+
const list = processManager.list(TEST_SESSION);
|
|
60
|
+
expect(list.length).toBe(0);
|
|
61
|
+
});
|
|
62
|
+
it("executes through createProcessTool wrapper", async () => {
|
|
63
|
+
const tool = createProcessTool(TEST_SESSION, process.cwd());
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
const execTool = tool.execute;
|
|
66
|
+
const startRes = await execTool("call-1", {
|
|
67
|
+
action: "start",
|
|
68
|
+
name: "tool-test",
|
|
69
|
+
command: "node -e 'console.log(\"from-tool\"); setInterval(() => {}, 100)'",
|
|
70
|
+
});
|
|
71
|
+
expect(startRes.details.success).toBe(true);
|
|
72
|
+
const procId = startRes.details.process.id;
|
|
73
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
74
|
+
const listRes = await execTool("call-2", { action: "list" });
|
|
75
|
+
expect(listRes.details.success).toBe(true);
|
|
76
|
+
expect(listRes.details.processes.length).toBe(1);
|
|
77
|
+
const outRes = await execTool("call-3", { action: "output", id: procId });
|
|
78
|
+
expect(outRes.details.success).toBe(true);
|
|
79
|
+
const firstContent = outRes.content[0];
|
|
80
|
+
expect(firstContent.text).toContain("from-tool");
|
|
81
|
+
const killRes = await execTool("call-4", { action: "kill", id: procId });
|
|
82
|
+
expect(killRes.details.success).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=processes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processes.test.js","sourceRoot":"","sources":["../../src/processes/processes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt snippets and guidelines for the background process tool.
|
|
3
|
+
*/
|
|
4
|
+
export declare const PROMPT_SNIPPET = "Manage background processes without blocking the conversation";
|
|
5
|
+
export declare const PROMPT_GUIDELINES: string[];
|
|
6
|
+
export declare const TOOL_DESCRIPTION = "Manage background processes. Actions:\n- start: Run command in background (requires 'name' and 'command')\n - alertOnSuccess (default: false): Show an informational notification on clean completion; does not wake the agent\n - alertOnFailure (default: true): Get a turn to react when process crashes/fails\n - alertOnKill (default: false): Get a turn to react if killed by external signal (killing via tool never triggers a turn)\n - logWatches (optional): Runtime output watches that trigger immediate alerts while running\n - pattern: regex string to match per output line\n - stream: stdout | stderr | both (default both)\n - repeat: false by default (single-fire). Set true for repeat alerts\n- list: Show all managed processes with their IDs and names\n- output: Get recent stdout/stderr (requires 'id')\n- logs: Get log file paths to inspect with read tool (requires 'id')\n- kill: Terminate a process (requires 'id')\n- clear: Remove all finished processes from the list\n- write: Write to process stdin (requires 'id' and 'input', optional 'end' to close stdin)\n\nImportant: Use bash when you need a command's result before continuing in the current turn. Use process for asynchronous/background work only. You DON'T need to poll or wait for processes. Do not repeatedly call list/output after start just to check whether the process has completed. Start processes and continue other work.";
|
|
7
|
+
//# sourceMappingURL=prompt-strings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-strings.d.ts","sourceRoot":"","sources":["../../src/processes/prompt-strings.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,kEAAkE,CAAC;AAE9F,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAKrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,w4CAgByS,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt snippets and guidelines for the background process tool.
|
|
3
|
+
*/
|
|
4
|
+
export const PROMPT_SNIPPET = "Manage background processes without blocking the conversation";
|
|
5
|
+
export const PROMPT_GUIDELINES = [
|
|
6
|
+
"Use the process tool for long-running commands such as dev servers, test watchers, build watchers, and log tails instead of bash.",
|
|
7
|
+
"Avoid shell background patterns such as &, nohup, disown, or setsid when the process tool fits.",
|
|
8
|
+
"After starting a process, continue other work instead of waiting for it. Do not repeatedly call list/output just to see whether it has finished.",
|
|
9
|
+
"Use bash instead when you need a command's result before continuing. Use process notify flags/logWatches only for asynchronous follow-up, especially failures or specific output patterns.",
|
|
10
|
+
];
|
|
11
|
+
export const TOOL_DESCRIPTION = `Manage background processes. Actions:
|
|
12
|
+
- start: Run command in background (requires 'name' and 'command')
|
|
13
|
+
- alertOnSuccess (default: false): Show an informational notification on clean completion; does not wake the agent
|
|
14
|
+
- alertOnFailure (default: true): Get a turn to react when process crashes/fails
|
|
15
|
+
- alertOnKill (default: false): Get a turn to react if killed by external signal (killing via tool never triggers a turn)
|
|
16
|
+
- logWatches (optional): Runtime output watches that trigger immediate alerts while running
|
|
17
|
+
- pattern: regex string to match per output line
|
|
18
|
+
- stream: stdout | stderr | both (default both)
|
|
19
|
+
- repeat: false by default (single-fire). Set true for repeat alerts
|
|
20
|
+
- list: Show all managed processes with their IDs and names
|
|
21
|
+
- output: Get recent stdout/stderr (requires 'id')
|
|
22
|
+
- logs: Get log file paths to inspect with read tool (requires 'id')
|
|
23
|
+
- kill: Terminate a process (requires 'id')
|
|
24
|
+
- clear: Remove all finished processes from the list
|
|
25
|
+
- write: Write to process stdin (requires 'id' and 'input', optional 'end' to close stdin)
|
|
26
|
+
|
|
27
|
+
Important: Use bash when you need a command's result before continuing in the current turn. Use process for asynchronous/background work only. You DON'T need to poll or wait for processes. Do not repeatedly call list/output after start just to check whether the process has completed. Start processes and continue other work.`;
|
|
28
|
+
//# sourceMappingURL=prompt-strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-strings.js","sourceRoot":"","sources":["../../src/processes/prompt-strings.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,+DAA+D,CAAC;AAE9F,MAAM,CAAC,MAAM,iBAAiB,GAAa;IACzC,mIAAmI;IACnI,iGAAiG;IACjG,kJAAkJ;IAClJ,4LAA4L;CAC7L,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;sUAgBsS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/processes/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAyFtE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc,CAsH1F"}
|