@felan-ai/ext-background-bash 0.3.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/LICENSE +22 -0
- package/NOTICE +12 -0
- package/README.md +52 -0
- package/dist/command-normalizer.d.ts +7 -0
- package/dist/command-normalizer.d.ts.map +1 -0
- package/dist/command-normalizer.js +23 -0
- package/dist/command-normalizer.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +515 -0
- package/dist/index.js.map +1 -0
- package/dist/job-store.d.ts +84 -0
- package/dist/job-store.d.ts.map +1 -0
- package/dist/job-store.js +349 -0
- package/dist/job-store.js.map +1 -0
- package/dist/logs.d.ts +5 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +44 -0
- package/dist/logs.js.map +1 -0
- package/dist/process-manager.d.ts +18 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +292 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/ui/background-bash-overlay.d.ts +39 -0
- package/dist/ui/background-bash-overlay.d.ts.map +1 -0
- package/dist/ui/background-bash-overlay.js +352 -0
- package/dist/ui/background-bash-overlay.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { createOutputLog, readLogTail } from './logs.js';
|
|
2
|
+
import { BackgroundBashJobStore, isTerminalStatus, } from './job-store.js';
|
|
3
|
+
const WAIT_POLL_MS = 500;
|
|
4
|
+
const PID_STARTUP_GRACE_MS = 5_000;
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
export class BackgroundBashManager {
|
|
7
|
+
runtime;
|
|
8
|
+
#store;
|
|
9
|
+
constructor(runtime) {
|
|
10
|
+
this.runtime = runtime;
|
|
11
|
+
this.#store = new BackgroundBashJobStore(runtime);
|
|
12
|
+
}
|
|
13
|
+
async start(command) {
|
|
14
|
+
let job = await this.#store.createJob(command);
|
|
15
|
+
await createOutputLog(this.runtime.storage, job.meta.logPath);
|
|
16
|
+
await this.runtime.storage.writeFile(job.meta.commandPath, encoder.encode(`${command}\n`));
|
|
17
|
+
await this.runtime.storage.writeFile(job.meta.runnerPath, encoder.encode(createRunnerScript(job)));
|
|
18
|
+
try {
|
|
19
|
+
const launch = await this.runtime.shell(createLaunchCommand(job.meta.runnerPath, job.meta.processToken), {
|
|
20
|
+
cwd: this.runtime.cwd,
|
|
21
|
+
timeout: 10_000,
|
|
22
|
+
});
|
|
23
|
+
if (launch.killed || launch.code !== 0) {
|
|
24
|
+
throw new Error(launch.stderr || launch.stdout || 'Background runner failed to launch');
|
|
25
|
+
}
|
|
26
|
+
const launchedProcess = parseLaunchResult(launch.stdout);
|
|
27
|
+
if (!launchedProcess)
|
|
28
|
+
throw new Error('Background runner did not report a process id');
|
|
29
|
+
job = await this.#store.updatePid(job.meta.id, launchedProcess.pid, launchedProcess.processGroupId) ?? job;
|
|
30
|
+
return job;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
await this.#store.markStatus(job.meta.id, {
|
|
34
|
+
status: 'failed',
|
|
35
|
+
exitCode: null,
|
|
36
|
+
signal: null,
|
|
37
|
+
error: errorMessage(error),
|
|
38
|
+
});
|
|
39
|
+
throw new Error(`Failed to start background bash process: ${errorMessage(error)}`, { cause: error });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async list(status = 'all') {
|
|
43
|
+
const jobs = await this.#store.listJobs('all');
|
|
44
|
+
const normalized = [];
|
|
45
|
+
for (const job of jobs)
|
|
46
|
+
normalized.push(await this.#normalizeJob(job));
|
|
47
|
+
return status === 'all'
|
|
48
|
+
? normalized
|
|
49
|
+
: normalized.filter((job) => job.status.status === status);
|
|
50
|
+
}
|
|
51
|
+
async get(id) {
|
|
52
|
+
const job = await this.#store.readJob(id);
|
|
53
|
+
if (!job)
|
|
54
|
+
throw new Error(`Background Bash process not found: ${id}`);
|
|
55
|
+
return this.#normalizeJob(job);
|
|
56
|
+
}
|
|
57
|
+
async wait(id, timeoutSeconds, signal) {
|
|
58
|
+
const deadline = timeoutSeconds === undefined
|
|
59
|
+
? undefined
|
|
60
|
+
: Date.now() + Math.max(0, timeoutSeconds) * 1_000;
|
|
61
|
+
while (true) {
|
|
62
|
+
const job = await this.get(id);
|
|
63
|
+
if (isTerminalStatus(job.status.status))
|
|
64
|
+
return { job, timedOut: false };
|
|
65
|
+
if (deadline !== undefined && Date.now() >= deadline)
|
|
66
|
+
return { job, timedOut: true };
|
|
67
|
+
const delay = deadline === undefined
|
|
68
|
+
? WAIT_POLL_MS
|
|
69
|
+
: Math.max(0, Math.min(WAIT_POLL_MS, deadline - Date.now()));
|
|
70
|
+
await sleep(delay, signal);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async stop(id, signal = 'SIGTERM') {
|
|
74
|
+
const job = await this.get(id);
|
|
75
|
+
if (isTerminalStatus(job.status.status))
|
|
76
|
+
return job;
|
|
77
|
+
const pid = job.status.pid ?? job.meta.pid;
|
|
78
|
+
const inspected = pid ? await this.#inspectJobProcess(job, pid) : undefined;
|
|
79
|
+
if (!pid || !inspected) {
|
|
80
|
+
const unknown = await this.#store.markStatus(id, {
|
|
81
|
+
status: 'unknown',
|
|
82
|
+
...(pid === undefined ? {} : { pid }),
|
|
83
|
+
exitCode: null,
|
|
84
|
+
signal: null,
|
|
85
|
+
error: pid ? 'Process is no longer alive.' : 'No process id was recorded.',
|
|
86
|
+
});
|
|
87
|
+
if (!unknown)
|
|
88
|
+
throw new Error(`Background Bash process not found: ${id}`);
|
|
89
|
+
return unknown;
|
|
90
|
+
}
|
|
91
|
+
let result = inspected?.processGroupId === pid
|
|
92
|
+
? await this.#sendSignal(-inspected.processGroupId, signal)
|
|
93
|
+
: await this.#sendSignal(pid, signal);
|
|
94
|
+
if (result.code !== 0 && inspected?.processGroupId === pid) {
|
|
95
|
+
result = await this.#sendSignal(pid, signal);
|
|
96
|
+
}
|
|
97
|
+
if (result.code !== 0) {
|
|
98
|
+
throw new Error(result.stderr || `Unable to send ${signal} to Background Bash process ${id}`);
|
|
99
|
+
}
|
|
100
|
+
const killed = await this.#store.markStatus(id, {
|
|
101
|
+
status: 'killed',
|
|
102
|
+
pid,
|
|
103
|
+
exitCode: null,
|
|
104
|
+
signal,
|
|
105
|
+
});
|
|
106
|
+
if (!killed)
|
|
107
|
+
throw new Error(`Background Bash process not found: ${id}`);
|
|
108
|
+
return killed;
|
|
109
|
+
}
|
|
110
|
+
async tail(id, lines = 80) {
|
|
111
|
+
const job = await this.get(id);
|
|
112
|
+
return readLogTail(this.runtime.storage, job.meta.logPath, lines);
|
|
113
|
+
}
|
|
114
|
+
async #normalizeJob(job) {
|
|
115
|
+
if (job.status.status !== 'running')
|
|
116
|
+
return job;
|
|
117
|
+
const pid = job.status.pid ?? job.meta.pid;
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
if (!pid && now - job.status.startedAt <= PID_STARTUP_GRACE_MS)
|
|
120
|
+
return job;
|
|
121
|
+
if (pid && await this.#isJobProcessAlive(job, pid))
|
|
122
|
+
return job;
|
|
123
|
+
return await this.#store.markStatus(job.meta.id, {
|
|
124
|
+
status: 'unknown',
|
|
125
|
+
...(pid === undefined ? {} : { pid }),
|
|
126
|
+
exitCode: null,
|
|
127
|
+
signal: null,
|
|
128
|
+
error: pid
|
|
129
|
+
? 'Process is no longer alive and no terminal status was written.'
|
|
130
|
+
: 'No process id was recorded and no terminal status was written.',
|
|
131
|
+
}) ?? job;
|
|
132
|
+
}
|
|
133
|
+
async #isJobProcessAlive(job, pid) {
|
|
134
|
+
return await this.#inspectJobProcess(job, pid) !== undefined;
|
|
135
|
+
}
|
|
136
|
+
async #inspectJobProcess(job, pid) {
|
|
137
|
+
const result = await this.runtime.exec('ps', ['-o', 'pgid=', '-o', 'command=', '-p', String(pid)], { cwd: this.runtime.cwd });
|
|
138
|
+
if (result.code !== 0)
|
|
139
|
+
return undefined;
|
|
140
|
+
const match = result.stdout.match(/^\s*(\d+)\s+([\s\S]+?)\s*$/u);
|
|
141
|
+
if (!match)
|
|
142
|
+
return undefined;
|
|
143
|
+
const processGroupId = Number(match[1]);
|
|
144
|
+
if (!Number.isSafeInteger(processGroupId) || processGroupId <= 0)
|
|
145
|
+
return undefined;
|
|
146
|
+
const command = match[2] ?? '';
|
|
147
|
+
if (job.meta.processToken) {
|
|
148
|
+
if (!command.includes(job.meta.runnerPath) || !command.includes(job.meta.processToken))
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
else if (!command.includes(job.meta.runnerPath)
|
|
152
|
+
&& !(command.includes('PI_BG_INFO_PATH') && command.includes('PI_BG_COMMAND'))) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
return { processGroupId };
|
|
156
|
+
}
|
|
157
|
+
#sendSignal(pid, signal) {
|
|
158
|
+
return this.runtime.exec('kill', [`-${signal.slice(3)}`, String(pid)], { cwd: this.runtime.cwd });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function createLaunchCommand(runnerPath, processToken) {
|
|
162
|
+
const path = shellQuote(runnerPath);
|
|
163
|
+
const token = shellQuote(processToken);
|
|
164
|
+
return [
|
|
165
|
+
'if command -v setsid >/dev/null 2>&1; then',
|
|
166
|
+
` nohup setsid sh ${path} ${token} >/dev/null 2>&1 < /dev/null &`,
|
|
167
|
+
' pid="$!"',
|
|
168
|
+
" printf 'group:%s:%s\\n' \"$pid\" \"$pid\"",
|
|
169
|
+
'else',
|
|
170
|
+
' set -m 2>/dev/null || true',
|
|
171
|
+
` nohup sh ${path} ${token} >/dev/null 2>&1 < /dev/null &`,
|
|
172
|
+
' pid="$!"',
|
|
173
|
+
" process_group=$(ps -o pgid= -p \"$pid\" 2>/dev/null | tr -d ' ')",
|
|
174
|
+
' if [ "$process_group" = "$pid" ]; then',
|
|
175
|
+
" printf 'group:%s:%s\\n' \"$pid\" \"$process_group\"",
|
|
176
|
+
' else',
|
|
177
|
+
' kill "$pid" 2>/dev/null',
|
|
178
|
+
' wait "$pid" 2>/dev/null',
|
|
179
|
+
" printf '%s\\n' 'Unable to create a detached process group' >&2",
|
|
180
|
+
' exit 1',
|
|
181
|
+
' fi',
|
|
182
|
+
'fi',
|
|
183
|
+
].join('\n');
|
|
184
|
+
}
|
|
185
|
+
function createRunnerScript(job) {
|
|
186
|
+
const id = shellQuote(job.meta.id);
|
|
187
|
+
const commandPath = shellQuote(job.meta.commandPath);
|
|
188
|
+
const completionPath = shellQuote(job.meta.completionPath);
|
|
189
|
+
const outputPath = shellQuote(job.meta.logPath);
|
|
190
|
+
return `#!/bin/sh
|
|
191
|
+
set +e
|
|
192
|
+
job_id=${id}
|
|
193
|
+
command_path=${commandPath}
|
|
194
|
+
completion_path=${completionPath}
|
|
195
|
+
output_path=${outputPath}
|
|
196
|
+
started_at=${job.meta.startedAt}
|
|
197
|
+
child_pid=
|
|
198
|
+
|
|
199
|
+
write_completion() {
|
|
200
|
+
status="$1"
|
|
201
|
+
exit_code="$2"
|
|
202
|
+
signal_name="$3"
|
|
203
|
+
completed_at=$(($(date +%s) * 1000))
|
|
204
|
+
if [ "$signal_name" = "null" ]; then
|
|
205
|
+
signal_json=null
|
|
206
|
+
else
|
|
207
|
+
signal_json="\\\"$signal_name\\\""
|
|
208
|
+
fi
|
|
209
|
+
tmp_path="$completion_path.$$.$completed_at.tmp"
|
|
210
|
+
cat > "$tmp_path" <<EOF
|
|
211
|
+
{
|
|
212
|
+
"id": "$job_id",
|
|
213
|
+
"status": "$status",
|
|
214
|
+
"startedAt": $started_at,
|
|
215
|
+
"updatedAt": $completed_at,
|
|
216
|
+
"pid": $$,
|
|
217
|
+
"exitCode": $exit_code,
|
|
218
|
+
"signal": $signal_json,
|
|
219
|
+
"completedAt": $completed_at
|
|
220
|
+
}
|
|
221
|
+
EOF
|
|
222
|
+
mv "$tmp_path" "$completion_path"
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
terminate() {
|
|
226
|
+
signal_name="$1"
|
|
227
|
+
short_signal=\${signal_name#SIG}
|
|
228
|
+
if [ -n "$child_pid" ]; then
|
|
229
|
+
kill -"$short_signal" "$child_pid" 2>/dev/null
|
|
230
|
+
wait "$child_pid" 2>/dev/null
|
|
231
|
+
fi
|
|
232
|
+
write_completion killed null "$signal_name"
|
|
233
|
+
exit 143
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
trap 'terminate SIGTERM' TERM
|
|
237
|
+
trap 'terminate SIGINT' INT
|
|
238
|
+
trap 'terminate SIGHUP' HUP
|
|
239
|
+
|
|
240
|
+
sh "$command_path" >> "$output_path" 2>&1 &
|
|
241
|
+
child_pid=$!
|
|
242
|
+
wait "$child_pid"
|
|
243
|
+
exit_code=$?
|
|
244
|
+
trap - TERM INT HUP
|
|
245
|
+
|
|
246
|
+
if [ ! -f "$completion_path" ]; then
|
|
247
|
+
if [ "$exit_code" -eq 0 ]; then
|
|
248
|
+
write_completion completed "$exit_code" null
|
|
249
|
+
else
|
|
250
|
+
write_completion failed "$exit_code" null
|
|
251
|
+
fi
|
|
252
|
+
fi
|
|
253
|
+
exit "$exit_code"
|
|
254
|
+
`;
|
|
255
|
+
}
|
|
256
|
+
function parseLaunchResult(output) {
|
|
257
|
+
const match = output.trim().match(/(?:^|\n)(?:group:(\d+):(\d+)|pid:(\d+))$/u);
|
|
258
|
+
if (!match)
|
|
259
|
+
return undefined;
|
|
260
|
+
const pid = Number(match[1] ?? match[3]);
|
|
261
|
+
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
262
|
+
return undefined;
|
|
263
|
+
const processGroupId = match[2] === undefined ? undefined : Number(match[2]);
|
|
264
|
+
if (processGroupId !== undefined && (!Number.isSafeInteger(processGroupId) || processGroupId <= 0)) {
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
return { pid, ...(processGroupId === undefined ? {} : { processGroupId }) };
|
|
268
|
+
}
|
|
269
|
+
function shellQuote(value) {
|
|
270
|
+
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
271
|
+
}
|
|
272
|
+
function sleep(ms, signal) {
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
if (signal?.aborted) {
|
|
275
|
+
reject(new Error('aborted'));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const onAbort = () => {
|
|
279
|
+
clearTimeout(timeout);
|
|
280
|
+
reject(new Error('aborted'));
|
|
281
|
+
};
|
|
282
|
+
const timeout = setTimeout(() => {
|
|
283
|
+
signal?.removeEventListener('abort', onAbort);
|
|
284
|
+
resolve();
|
|
285
|
+
}, ms);
|
|
286
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function errorMessage(error) {
|
|
290
|
+
return error instanceof Error ? error.message : String(error);
|
|
291
|
+
}
|
|
292
|
+
//# 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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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ExtensionContext } from '@felan-ai/agent-core';
|
|
2
|
+
import type { BackgroundBashManager } from '../process-manager.js';
|
|
3
|
+
type Theme = ExtensionContext['ui']['theme'];
|
|
4
|
+
export declare class BackgroundBashOverlay {
|
|
5
|
+
private readonly manager;
|
|
6
|
+
private readonly theme;
|
|
7
|
+
private readonly done;
|
|
8
|
+
private readonly requestRender;
|
|
9
|
+
private jobs;
|
|
10
|
+
private selected;
|
|
11
|
+
private listScroll;
|
|
12
|
+
private logLines;
|
|
13
|
+
private logScroll;
|
|
14
|
+
private loading;
|
|
15
|
+
private message;
|
|
16
|
+
private view;
|
|
17
|
+
constructor(manager: BackgroundBashManager, theme: Theme, done: () => void, requestRender: () => void);
|
|
18
|
+
handleInput(data: string): void;
|
|
19
|
+
render(width: number): string[];
|
|
20
|
+
invalidate(): void;
|
|
21
|
+
private handleListInput;
|
|
22
|
+
private handleDetailInput;
|
|
23
|
+
private renderList;
|
|
24
|
+
private renderDetail;
|
|
25
|
+
private refresh;
|
|
26
|
+
private refreshDetail;
|
|
27
|
+
private refreshLog;
|
|
28
|
+
private selectListJob;
|
|
29
|
+
private openDetail;
|
|
30
|
+
private clampListScroll;
|
|
31
|
+
private scrollLog;
|
|
32
|
+
private scrollLogToBottom;
|
|
33
|
+
private clampLogScroll;
|
|
34
|
+
private stopSelected;
|
|
35
|
+
private killSelected;
|
|
36
|
+
private signalSelected;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=background-bash-overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-bash-overlay.d.ts","sourceRoot":"","sources":["../../src/ui/background-bash-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAQnE,KAAK,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;AAG7C,qBAAa,qBAAqB;IAW9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAbhC,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,IAAI,CAAuB;gBAGhB,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,IAAI,EAChB,aAAa,EAAE,MAAM,IAAI;IAK5C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAa/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAQ/B,UAAU,IAAI,IAAI;IAElB,OAAO,CAAC,eAAe;IA4CvB,OAAO,CAAC,iBAAiB;IA2CzB,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,YAAY;YA4BN,OAAO;YAuBP,aAAa;YAKb,UAAU;IAoBxB,OAAO,CAAC,aAAa;YAOP,UAAU;IAMxB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;YAOR,YAAY;YAIZ,YAAY;YAIZ,cAAc;CAsB7B"}
|