lsh-framework 1.2.0 → 1.2.1
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 +40 -3
- package/dist/cli.js +104 -486
- package/dist/commands/doctor.js +427 -0
- package/dist/commands/init.js +371 -0
- package/dist/constants/api.js +94 -0
- package/dist/constants/commands.js +64 -0
- package/dist/constants/config.js +56 -0
- package/dist/constants/database.js +21 -0
- package/dist/constants/errors.js +79 -0
- package/dist/constants/index.js +28 -0
- package/dist/constants/paths.js +28 -0
- package/dist/constants/ui.js +73 -0
- package/dist/constants/validation.js +124 -0
- package/dist/daemon/lshd.js +11 -32
- package/dist/lib/daemon-client-helper.js +7 -4
- package/dist/lib/daemon-client.js +9 -2
- package/dist/lib/format-utils.js +163 -0
- package/dist/lib/job-manager.js +2 -1
- package/dist/lib/platform-utils.js +211 -0
- package/dist/lib/secrets-manager.js +11 -1
- package/dist/lib/string-utils.js +128 -0
- package/dist/services/daemon/daemon-registrar.js +3 -2
- package/dist/services/secrets/secrets.js +54 -30
- package/package.json +10 -74
- package/dist/app.js +0 -33
- package/dist/cicd/analytics.js +0 -261
- package/dist/cicd/auth.js +0 -269
- package/dist/cicd/cache-manager.js +0 -172
- package/dist/cicd/data-retention.js +0 -305
- package/dist/cicd/performance-monitor.js +0 -224
- package/dist/cicd/webhook-receiver.js +0 -640
- package/dist/commands/api.js +0 -346
- package/dist/commands/theme.js +0 -261
- package/dist/commands/zsh-import.js +0 -240
- package/dist/components/App.js +0 -1
- package/dist/components/Divider.js +0 -29
- package/dist/components/REPL.js +0 -43
- package/dist/components/Terminal.js +0 -232
- package/dist/components/UserInput.js +0 -30
- package/dist/daemon/api-server.js +0 -316
- package/dist/daemon/monitoring-api.js +0 -220
- package/dist/lib/api-error-handler.js +0 -185
- package/dist/lib/associative-arrays.js +0 -285
- package/dist/lib/base-api-server.js +0 -290
- package/dist/lib/brace-expansion.js +0 -160
- package/dist/lib/builtin-commands.js +0 -439
- package/dist/lib/executors/builtin-executor.js +0 -52
- package/dist/lib/extended-globbing.js +0 -411
- package/dist/lib/extended-parameter-expansion.js +0 -227
- package/dist/lib/interactive-shell.js +0 -460
- package/dist/lib/job-builtins.js +0 -582
- package/dist/lib/pathname-expansion.js +0 -216
- package/dist/lib/script-runner.js +0 -226
- package/dist/lib/shell-executor.js +0 -2504
- package/dist/lib/shell-parser.js +0 -958
- package/dist/lib/shell-types.js +0 -6
- package/dist/lib/shell.lib.js +0 -40
- package/dist/lib/theme-manager.js +0 -476
- package/dist/lib/variable-expansion.js +0 -385
- package/dist/lib/zsh-compatibility.js +0 -659
- package/dist/lib/zsh-import-manager.js +0 -707
- package/dist/lib/zsh-options.js +0 -328
- package/dist/pipeline/job-tracker.js +0 -491
- package/dist/pipeline/mcli-bridge.js +0 -309
- package/dist/pipeline/pipeline-service.js +0 -1119
- package/dist/pipeline/workflow-engine.js +0 -870
- package/dist/services/api/api.js +0 -58
- package/dist/services/api/auth.js +0 -35
- package/dist/services/api/config.js +0 -7
- package/dist/services/api/file.js +0 -22
- package/dist/services/shell/shell.js +0 -28
- package/dist/services/zapier.js +0 -16
- package/dist/simple-api-server.js +0 -148
package/dist/lib/job-builtins.js
DELETED
|
@@ -1,582 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in commands for comprehensive job management
|
|
3
|
-
*/
|
|
4
|
-
export class JobBuiltins {
|
|
5
|
-
jobManager;
|
|
6
|
-
constructor(jobManager) {
|
|
7
|
-
this.jobManager = jobManager;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* job-create - Create a new job
|
|
11
|
-
* Usage: job-create [OPTIONS] COMMAND
|
|
12
|
-
*/
|
|
13
|
-
async jobCreate(args) {
|
|
14
|
-
try {
|
|
15
|
-
const options = this.parseCreateOptions(args);
|
|
16
|
-
const command = args.slice(args.findIndex(arg => !arg.startsWith('-'))).join(' ');
|
|
17
|
-
if (!command) {
|
|
18
|
-
return {
|
|
19
|
-
stdout: '',
|
|
20
|
-
stderr: 'Usage: job-create [OPTIONS] COMMAND\n' +
|
|
21
|
-
'Options:\n' +
|
|
22
|
-
' -n, --name NAME Job name\n' +
|
|
23
|
-
' -t, --type TYPE Job type (shell|system|scheduled)\n' +
|
|
24
|
-
' -p, --priority N Priority (-20 to 19)\n' +
|
|
25
|
-
' -d, --description D Description\n' +
|
|
26
|
-
' --timeout N Timeout in seconds\n' +
|
|
27
|
-
' --cwd PATH Working directory\n' +
|
|
28
|
-
' --log PATH Log file path\n' +
|
|
29
|
-
' --tag TAG Add tag (can be used multiple times)\n' +
|
|
30
|
-
' --schedule CRON Schedule with cron expression\n' +
|
|
31
|
-
' --interval N Run every N seconds\n' +
|
|
32
|
-
' --start Start immediately after creation',
|
|
33
|
-
exitCode: 1
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
const jobSpec = {
|
|
37
|
-
...options,
|
|
38
|
-
command
|
|
39
|
-
};
|
|
40
|
-
const job = await this.jobManager.createJob(jobSpec);
|
|
41
|
-
const extendedJob = job; // Cast to access extended properties
|
|
42
|
-
let output = `Job created: ${job.id}\n`;
|
|
43
|
-
output += ` Name: ${job.name}\n`;
|
|
44
|
-
output += ` Command: ${job.command}\n`;
|
|
45
|
-
output += ` Type: ${extendedJob.type || 'standard'}\n`;
|
|
46
|
-
output += ` Status: ${job.status}\n`;
|
|
47
|
-
if (options.start) {
|
|
48
|
-
await this.jobManager.startJob(job.id);
|
|
49
|
-
output += ` Started with PID: ${job.pid}\n`;
|
|
50
|
-
}
|
|
51
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* job-list - List jobs with filtering
|
|
59
|
-
* Usage: job-list [OPTIONS]
|
|
60
|
-
*/
|
|
61
|
-
async jobList(args) {
|
|
62
|
-
try {
|
|
63
|
-
const filter = this.parseListOptions(args);
|
|
64
|
-
const jobs = await this.jobManager.listJobs(filter);
|
|
65
|
-
if (jobs.length === 0) {
|
|
66
|
-
return { stdout: 'No jobs found.\n', stderr: '', exitCode: 0 };
|
|
67
|
-
}
|
|
68
|
-
let output = '';
|
|
69
|
-
const detailed = args.includes('-l') || args.includes('--long');
|
|
70
|
-
const showAll = args.includes('-a') || args.includes('--all');
|
|
71
|
-
if (detailed) {
|
|
72
|
-
for (const job of jobs) {
|
|
73
|
-
output += this.formatJobDetailed(job) + '\n';
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
output += 'ID NAME STATUS PID STARTED COMMAND\n';
|
|
78
|
-
output += '============================================================================\n';
|
|
79
|
-
for (const job of jobs) {
|
|
80
|
-
if (!showAll && job.status === 'completed' &&
|
|
81
|
-
job.completedAt &&
|
|
82
|
-
Date.now() - job.completedAt.getTime() > 24 * 60 * 60 * 1000) {
|
|
83
|
-
continue; // Skip old completed jobs unless --all
|
|
84
|
-
}
|
|
85
|
-
output += this.formatJobSummary(job) + '\n';
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* job-show - Show detailed information about a job
|
|
96
|
-
* Usage: job-show JOB_ID
|
|
97
|
-
*/
|
|
98
|
-
async jobShow(args) {
|
|
99
|
-
if (args.length === 0) {
|
|
100
|
-
return {
|
|
101
|
-
stdout: '',
|
|
102
|
-
stderr: 'Usage: job-show JOB_ID\n',
|
|
103
|
-
exitCode: 1
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
const jobId = args[0];
|
|
107
|
-
const job = await this.jobManager.getJob(jobId);
|
|
108
|
-
if (!job) {
|
|
109
|
-
return { stdout: '', stderr: `Job ${jobId} not found.\n`, exitCode: 1 };
|
|
110
|
-
}
|
|
111
|
-
const output = this.formatJobDetailed(job);
|
|
112
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* job-start - Start a created job
|
|
116
|
-
* Usage: job-start JOB_ID
|
|
117
|
-
*/
|
|
118
|
-
async jobStart(args) {
|
|
119
|
-
if (args.length === 0) {
|
|
120
|
-
return { stdout: '', stderr: 'Usage: job-start JOB_ID\n', exitCode: 1 };
|
|
121
|
-
}
|
|
122
|
-
try {
|
|
123
|
-
const jobId = args[0];
|
|
124
|
-
const job = await this.jobManager.startJob(jobId);
|
|
125
|
-
return {
|
|
126
|
-
stdout: `Job ${jobId} started with PID ${job.pid}\n`,
|
|
127
|
-
stderr: '',
|
|
128
|
-
exitCode: 0
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* job-stop - Stop/kill a running job
|
|
137
|
-
* Usage: job-stop [OPTIONS] JOB_ID
|
|
138
|
-
*/
|
|
139
|
-
async jobStop(args) {
|
|
140
|
-
if (args.length === 0) {
|
|
141
|
-
return {
|
|
142
|
-
stdout: '',
|
|
143
|
-
stderr: 'Usage: job-stop [OPTIONS] JOB_ID\n' +
|
|
144
|
-
'Options:\n' +
|
|
145
|
-
' -9, --kill Send SIGKILL instead of SIGTERM\n' +
|
|
146
|
-
' -s SIGNAL Send specific signal',
|
|
147
|
-
exitCode: 1
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
let signal = 'SIGTERM';
|
|
152
|
-
const jobId = args[args.length - 1];
|
|
153
|
-
for (let i = 0; i < args.length - 1; i++) {
|
|
154
|
-
if (args[i] === '-9' || args[i] === '--kill') {
|
|
155
|
-
signal = 'SIGKILL';
|
|
156
|
-
}
|
|
157
|
-
else if (args[i] === '-s' && i + 1 < args.length - 1) {
|
|
158
|
-
signal = args[i + 1];
|
|
159
|
-
i++;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
const _job = await this.jobManager.killJob(jobId, signal);
|
|
163
|
-
return {
|
|
164
|
-
stdout: `Job ${jobId} stopped with signal ${signal}\n`,
|
|
165
|
-
stderr: '',
|
|
166
|
-
exitCode: 0
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* job-pause - Pause a running job
|
|
175
|
-
* Usage: job-pause JOB_ID
|
|
176
|
-
*/
|
|
177
|
-
async jobPause(args) {
|
|
178
|
-
if (args.length === 0) {
|
|
179
|
-
return { stdout: '', stderr: 'Usage: job-pause JOB_ID\n', exitCode: 1 };
|
|
180
|
-
}
|
|
181
|
-
try {
|
|
182
|
-
const jobId = args[0];
|
|
183
|
-
await this.jobManager.pauseJob(jobId);
|
|
184
|
-
return { stdout: `Job ${jobId} paused\n`, stderr: '', exitCode: 0 };
|
|
185
|
-
}
|
|
186
|
-
catch (error) {
|
|
187
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* job-resume - Resume a paused job
|
|
192
|
-
* Usage: job-resume JOB_ID
|
|
193
|
-
*/
|
|
194
|
-
async jobResume(args) {
|
|
195
|
-
if (args.length === 0) {
|
|
196
|
-
return { stdout: '', stderr: 'Usage: job-resume JOB_ID\n', exitCode: 1 };
|
|
197
|
-
}
|
|
198
|
-
try {
|
|
199
|
-
const jobId = args[0];
|
|
200
|
-
await this.jobManager.resumeJob(jobId);
|
|
201
|
-
return { stdout: `Job ${jobId} resumed\n`, stderr: '', exitCode: 0 };
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* job-remove - Remove a job
|
|
209
|
-
* Usage: job-remove [OPTIONS] JOB_ID
|
|
210
|
-
*/
|
|
211
|
-
async jobRemove(args) {
|
|
212
|
-
if (args.length === 0) {
|
|
213
|
-
return {
|
|
214
|
-
stdout: '',
|
|
215
|
-
stderr: 'Usage: job-remove [OPTIONS] JOB_ID\n' +
|
|
216
|
-
'Options:\n' +
|
|
217
|
-
' -f, --force Force removal of running jobs',
|
|
218
|
-
exitCode: 1
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
let force = false;
|
|
223
|
-
const jobId = args[args.length - 1];
|
|
224
|
-
for (const arg of args.slice(0, -1)) {
|
|
225
|
-
if (arg === '-f' || arg === '--force') {
|
|
226
|
-
force = true;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
const removed = await this.jobManager.removeJob(jobId, force);
|
|
230
|
-
if (removed) {
|
|
231
|
-
return { stdout: `Job ${jobId} removed\n`, stderr: '', exitCode: 0 };
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
return { stdout: '', stderr: `Job ${jobId} not found\n`, exitCode: 1 };
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* job-update - Update job properties
|
|
243
|
-
* Usage: job-update [OPTIONS] JOB_ID
|
|
244
|
-
*/
|
|
245
|
-
async jobUpdate(args) {
|
|
246
|
-
if (args.length < 2) {
|
|
247
|
-
return {
|
|
248
|
-
stdout: '',
|
|
249
|
-
stderr: 'Usage: job-update [OPTIONS] JOB_ID\n' +
|
|
250
|
-
'Options:\n' +
|
|
251
|
-
' -n, --name NAME Change job name\n' +
|
|
252
|
-
' -p, --priority N Change priority (-20 to 19)\n' +
|
|
253
|
-
' -d, --description D Change description\n' +
|
|
254
|
-
' --timeout N Change timeout in seconds\n' +
|
|
255
|
-
' --add-tag TAG Add tag\n' +
|
|
256
|
-
' --remove-tag TAG Remove tag',
|
|
257
|
-
exitCode: 1
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
try {
|
|
261
|
-
const jobId = args[args.length - 1];
|
|
262
|
-
const updates = this.parseUpdateOptions(args.slice(0, -1));
|
|
263
|
-
const _job = await this.jobManager.updateJob(jobId, updates);
|
|
264
|
-
return { stdout: `Job ${jobId} updated successfully\n`, stderr: '', exitCode: 0 };
|
|
265
|
-
}
|
|
266
|
-
catch (error) {
|
|
267
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* job-run - Create and immediately start a job
|
|
272
|
-
* Usage: job-run [OPTIONS] COMMAND
|
|
273
|
-
*/
|
|
274
|
-
async jobRun(args) {
|
|
275
|
-
try {
|
|
276
|
-
const options = this.parseCreateOptions(args);
|
|
277
|
-
const command = args.slice(args.findIndex(arg => !arg.startsWith('-'))).join(' ');
|
|
278
|
-
if (!command) {
|
|
279
|
-
return { stdout: '', stderr: 'Usage: job-run [OPTIONS] COMMAND\n', exitCode: 1 };
|
|
280
|
-
}
|
|
281
|
-
const job = await this.jobManager.runJob({ ...options, command });
|
|
282
|
-
return {
|
|
283
|
-
stdout: `Job ${job.id} (${job.name}) started with PID ${job.pid}\n`,
|
|
284
|
-
stderr: '',
|
|
285
|
-
exitCode: 0
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* job-monitor - Monitor job resource usage
|
|
294
|
-
* Usage: job-monitor JOB_ID
|
|
295
|
-
*/
|
|
296
|
-
async jobMonitor(args) {
|
|
297
|
-
if (args.length === 0) {
|
|
298
|
-
return { stdout: '', stderr: 'Usage: job-monitor JOB_ID\n', exitCode: 1 };
|
|
299
|
-
}
|
|
300
|
-
try {
|
|
301
|
-
const jobId = args[0];
|
|
302
|
-
const monitoring = await this.jobManager.monitorJob(jobId);
|
|
303
|
-
if (!monitoring) {
|
|
304
|
-
return { stdout: '', stderr: `Job ${jobId} is not running\n`, exitCode: 1 };
|
|
305
|
-
}
|
|
306
|
-
let output = `Job ${jobId} Resource Usage:\n`;
|
|
307
|
-
output += ` PID: ${monitoring.pid}\n`;
|
|
308
|
-
output += ` CPU: ${monitoring.cpu}%\n`;
|
|
309
|
-
output += ` Memory: ${monitoring.memory}%\n`;
|
|
310
|
-
output += ` Elapsed: ${monitoring.elapsed}\n`;
|
|
311
|
-
output += ` State: ${monitoring.state}\n`;
|
|
312
|
-
output += ` Timestamp: ${monitoring.timestamp.toISOString()}\n`;
|
|
313
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
314
|
-
}
|
|
315
|
-
catch (error) {
|
|
316
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* job-stats - Show job statistics
|
|
321
|
-
* Usage: job-stats
|
|
322
|
-
*/
|
|
323
|
-
async jobStats(_args) {
|
|
324
|
-
try {
|
|
325
|
-
const stats = this.jobManager.getJobStats();
|
|
326
|
-
let output = 'Job Statistics:\n';
|
|
327
|
-
output += ` Total Jobs: ${stats.total}\n`;
|
|
328
|
-
output += ` Running: ${stats.running}\n`;
|
|
329
|
-
output += ` Completed: ${stats.completed}\n`;
|
|
330
|
-
output += ` Failed: ${stats.failed}\n\n`;
|
|
331
|
-
output += 'By Status:\n';
|
|
332
|
-
for (const [status, count] of Object.entries(stats.byStatus)) {
|
|
333
|
-
output += ` ${status}: ${count}\n`;
|
|
334
|
-
}
|
|
335
|
-
output += '\nBy Type:\n';
|
|
336
|
-
for (const [type, count] of Object.entries(stats.byType)) {
|
|
337
|
-
output += ` ${type}: ${count}\n`;
|
|
338
|
-
}
|
|
339
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
340
|
-
}
|
|
341
|
-
catch (error) {
|
|
342
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* job-cleanup - Clean up old completed jobs
|
|
347
|
-
* Usage: job-cleanup [HOURS]
|
|
348
|
-
*/
|
|
349
|
-
async jobCleanup(args) {
|
|
350
|
-
try {
|
|
351
|
-
const hours = args.length > 0 ? parseInt(args[0]) : 24;
|
|
352
|
-
const removed = await this.jobManager.cleanupJobs(hours);
|
|
353
|
-
return {
|
|
354
|
-
stdout: `Cleaned up ${removed} old jobs (older than ${hours} hours)\n`,
|
|
355
|
-
stderr: '',
|
|
356
|
-
exitCode: 0
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
catch (error) {
|
|
360
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* ps-list - List system processes
|
|
365
|
-
* Usage: ps-list [OPTIONS]
|
|
366
|
-
*/
|
|
367
|
-
async psList(args) {
|
|
368
|
-
try {
|
|
369
|
-
const processes = await this.jobManager.getSystemProcesses();
|
|
370
|
-
if (processes.length === 0) {
|
|
371
|
-
return { stdout: 'No processes found.\n', stderr: '', exitCode: 0 };
|
|
372
|
-
}
|
|
373
|
-
let output = 'PID PPID USER CPU% MEM% STARTED COMMAND\n';
|
|
374
|
-
output += '================================================================================\n';
|
|
375
|
-
const filtered = args.includes('--user')
|
|
376
|
-
? processes.filter(p => p.user === process.env.USER)
|
|
377
|
-
: processes;
|
|
378
|
-
const sorted = filtered.sort((a, b) => {
|
|
379
|
-
if (args.includes('--cpu'))
|
|
380
|
-
return b.cpu - a.cpu;
|
|
381
|
-
if (args.includes('--memory'))
|
|
382
|
-
return b.memory - a.memory;
|
|
383
|
-
return a.pid - b.pid;
|
|
384
|
-
});
|
|
385
|
-
const limit = args.includes('--top') ? 20 : sorted.length;
|
|
386
|
-
for (const proc of sorted.slice(0, limit)) {
|
|
387
|
-
output += `${proc.pid.toString().padEnd(8)} `;
|
|
388
|
-
output += `${proc.ppid.toString().padEnd(8)} `;
|
|
389
|
-
output += `${proc.user.padEnd(14)} `;
|
|
390
|
-
output += `${proc.cpu.toFixed(1).padStart(5)} `;
|
|
391
|
-
output += `${proc.memory.toFixed(1).padStart(5)} `;
|
|
392
|
-
output += `${proc.startTime.toLocaleString().padEnd(19)} `;
|
|
393
|
-
output += `${proc.command.slice(0, 50)}\n`;
|
|
394
|
-
}
|
|
395
|
-
return { stdout: output, stderr: '', exitCode: 0 };
|
|
396
|
-
}
|
|
397
|
-
catch (error) {
|
|
398
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* ps-kill - Kill a system process
|
|
403
|
-
* Usage: ps-kill [OPTIONS] PID
|
|
404
|
-
*/
|
|
405
|
-
async psKill(args) {
|
|
406
|
-
if (args.length === 0) {
|
|
407
|
-
return {
|
|
408
|
-
stdout: '',
|
|
409
|
-
stderr: 'Usage: ps-kill [OPTIONS] PID\n' +
|
|
410
|
-
'Options:\n' +
|
|
411
|
-
' -9, --kill Send SIGKILL instead of SIGTERM\n' +
|
|
412
|
-
' -s SIGNAL Send specific signal',
|
|
413
|
-
exitCode: 1
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
try {
|
|
417
|
-
let _signal = 'SIGTERM';
|
|
418
|
-
const pidStr = args[args.length - 1];
|
|
419
|
-
const pid = parseInt(pidStr);
|
|
420
|
-
if (isNaN(pid)) {
|
|
421
|
-
return { stdout: '', stderr: 'Invalid PID\n', exitCode: 1 };
|
|
422
|
-
}
|
|
423
|
-
for (let i = 0; i < args.length - 1; i++) {
|
|
424
|
-
if (args[i] === '-9' || args[i] === '--kill') {
|
|
425
|
-
_signal = 'SIGKILL';
|
|
426
|
-
}
|
|
427
|
-
else if (args[i] === '-s' && i + 1 < args.length - 1) {
|
|
428
|
-
_signal = args[i + 1];
|
|
429
|
-
i++;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
// TODO: Implement system process killing
|
|
433
|
-
// This functionality was removed during refactoring
|
|
434
|
-
return { stdout: '', stderr: `System process killing not yet implemented in refactored job manager\n`, exitCode: 1 };
|
|
435
|
-
}
|
|
436
|
-
catch (error) {
|
|
437
|
-
return { stdout: '', stderr: `Error: ${error.message}\n`, exitCode: 1 };
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
// Helper methods for parsing options and formatting output
|
|
441
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
442
|
-
parseCreateOptions(args) {
|
|
443
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
444
|
-
const options = { tags: [] };
|
|
445
|
-
for (let i = 0; i < args.length; i++) {
|
|
446
|
-
const arg = args[i];
|
|
447
|
-
if (arg === '-n' || arg === '--name') {
|
|
448
|
-
options.name = args[++i];
|
|
449
|
-
}
|
|
450
|
-
else if (arg === '-t' || arg === '--type') {
|
|
451
|
-
options.type = args[++i];
|
|
452
|
-
}
|
|
453
|
-
else if (arg === '-p' || arg === '--priority') {
|
|
454
|
-
options.priority = parseInt(args[++i]);
|
|
455
|
-
}
|
|
456
|
-
else if (arg === '-d' || arg === '--description') {
|
|
457
|
-
options.description = args[++i];
|
|
458
|
-
}
|
|
459
|
-
else if (arg === '--timeout') {
|
|
460
|
-
options.timeout = parseInt(args[++i]) * 1000;
|
|
461
|
-
}
|
|
462
|
-
else if (arg === '--cwd') {
|
|
463
|
-
options.cwd = args[++i];
|
|
464
|
-
}
|
|
465
|
-
else if (arg === '--log') {
|
|
466
|
-
options.logFile = args[++i];
|
|
467
|
-
}
|
|
468
|
-
else if (arg === '--tag') {
|
|
469
|
-
options.tags.push(args[++i]);
|
|
470
|
-
}
|
|
471
|
-
else if (arg === '--schedule') {
|
|
472
|
-
options.type = 'scheduled';
|
|
473
|
-
options.schedule = { cron: args[++i] };
|
|
474
|
-
}
|
|
475
|
-
else if (arg === '--interval') {
|
|
476
|
-
options.type = 'scheduled';
|
|
477
|
-
options.schedule = { interval: parseInt(args[++i]) * 1000 };
|
|
478
|
-
}
|
|
479
|
-
else if (arg === '--start') {
|
|
480
|
-
options.start = true;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return options;
|
|
484
|
-
}
|
|
485
|
-
parseListOptions(args) {
|
|
486
|
-
const filter = {};
|
|
487
|
-
for (let i = 0; i < args.length; i++) {
|
|
488
|
-
const arg = args[i];
|
|
489
|
-
if (arg === '--status') {
|
|
490
|
-
filter.status = args[++i].split(',');
|
|
491
|
-
}
|
|
492
|
-
else if (arg === '--type') {
|
|
493
|
-
filter.type = args[++i].split(',');
|
|
494
|
-
}
|
|
495
|
-
else if (arg === '--user') {
|
|
496
|
-
filter.user = args[++i];
|
|
497
|
-
}
|
|
498
|
-
else if (arg === '--tag') {
|
|
499
|
-
filter.tags = args[++i].split(',');
|
|
500
|
-
}
|
|
501
|
-
else if (arg === '--name') {
|
|
502
|
-
filter.namePattern = new RegExp(args[++i], 'i');
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
return filter;
|
|
506
|
-
}
|
|
507
|
-
parseUpdateOptions(args) {
|
|
508
|
-
const updates = {};
|
|
509
|
-
for (let i = 0; i < args.length; i++) {
|
|
510
|
-
const arg = args[i];
|
|
511
|
-
if (arg === '-n' || arg === '--name') {
|
|
512
|
-
updates.name = args[++i];
|
|
513
|
-
}
|
|
514
|
-
else if (arg === '-p' || arg === '--priority') {
|
|
515
|
-
updates.priority = parseInt(args[++i]);
|
|
516
|
-
}
|
|
517
|
-
else if (arg === '-d' || arg === '--description') {
|
|
518
|
-
updates.description = args[++i];
|
|
519
|
-
}
|
|
520
|
-
else if (arg === '--timeout') {
|
|
521
|
-
updates.timeout = parseInt(args[++i]) * 1000;
|
|
522
|
-
}
|
|
523
|
-
else if (arg === '--add-tag') {
|
|
524
|
-
if (!updates.tags)
|
|
525
|
-
updates.tags = [];
|
|
526
|
-
updates.tags.push(args[++i]);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return updates;
|
|
530
|
-
}
|
|
531
|
-
formatJobSummary(job) {
|
|
532
|
-
const id = job.id.padEnd(13);
|
|
533
|
-
const name = job.name.padEnd(20).slice(0, 20);
|
|
534
|
-
const status = job.status.padEnd(11);
|
|
535
|
-
const pid = (job.pid?.toString() || '-').padEnd(8);
|
|
536
|
-
const started = job.startedAt?.toLocaleString().slice(0, 19) || 'Not started';
|
|
537
|
-
const command = job.command.slice(0, 30);
|
|
538
|
-
return `${id} ${name} ${status} ${pid} ${started} ${command}`;
|
|
539
|
-
}
|
|
540
|
-
formatJobDetailed(job) {
|
|
541
|
-
const jobExt = job; // Cast to access extended properties
|
|
542
|
-
let output = `Job: ${job.id}\n`;
|
|
543
|
-
output += ` Name: ${job.name}\n`;
|
|
544
|
-
output += ` Command: ${job.command}\n`;
|
|
545
|
-
output += ` Type: ${jobExt.type || 'standard'}\n`;
|
|
546
|
-
output += ` Status: ${job.status}\n`;
|
|
547
|
-
output += ` Priority: ${job.priority}\n`;
|
|
548
|
-
output += ` Created: ${job.createdAt.toISOString()}\n`;
|
|
549
|
-
if (job.startedAt) {
|
|
550
|
-
output += ` Started: ${job.startedAt.toISOString()}\n`;
|
|
551
|
-
}
|
|
552
|
-
if (job.completedAt) {
|
|
553
|
-
output += ` Completed: ${job.completedAt.toISOString()}\n`;
|
|
554
|
-
}
|
|
555
|
-
if (job.pid) {
|
|
556
|
-
output += ` PID: ${job.pid}\n`;
|
|
557
|
-
}
|
|
558
|
-
if (jobExt.cpuUsage !== undefined) {
|
|
559
|
-
output += ` CPU Usage: ${jobExt.cpuUsage}%\n`;
|
|
560
|
-
}
|
|
561
|
-
if (jobExt.memoryUsage !== undefined) {
|
|
562
|
-
output += ` Memory Usage: ${jobExt.memoryUsage}%\n`;
|
|
563
|
-
}
|
|
564
|
-
if (job.cwd) {
|
|
565
|
-
output += ` Working Dir: ${job.cwd}\n`;
|
|
566
|
-
}
|
|
567
|
-
if (job.logFile) {
|
|
568
|
-
output += ` Log File: ${job.logFile}\n`;
|
|
569
|
-
}
|
|
570
|
-
if (job.tags && job.tags.length > 0) {
|
|
571
|
-
output += ` Tags: ${job.tags.join(', ')}\n`;
|
|
572
|
-
}
|
|
573
|
-
if (job.description) {
|
|
574
|
-
output += ` Description: ${job.description}\n`;
|
|
575
|
-
}
|
|
576
|
-
if (job.schedule) {
|
|
577
|
-
output += ` Schedule: ${JSON.stringify(job.schedule)}\n`;
|
|
578
|
-
}
|
|
579
|
-
return output;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
export default JobBuiltins;
|