@the-open-engine/zeroshot 6.31.2 → 6.32.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 +66 -98
- package/cli/index.js +251 -252
- package/cli/lib/setup-provider-readiness.js +86 -0
- package/cli/lib/setup-scanner-worker.js +120 -0
- package/cli/lib/setup-scanner.js +185 -0
- package/cli/lib/setup-wizard-input.js +146 -0
- package/cli/lib/setup-wizard-model.js +205 -0
- package/cli/lib/setup-wizard-plan-view.js +157 -0
- package/cli/lib/setup-wizard-scan-view.js +144 -0
- package/cli/lib/setup-wizard-terminal.js +237 -0
- package/cli/lib/setup-wizard-view.js +180 -0
- package/cli/lib/setup-wizard.js +281 -0
- package/cli/message-formatters-normal.js +14 -18
- package/cli/message-formatters-watch.js +53 -141
- package/lib/completion.js +102 -153
- package/lib/settings.js +10 -2
- package/lib/setup-apply.js +62 -55
- package/lib/setup-plan.js +32 -52
- package/lib/start-cluster.js +65 -25
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -3
- package/scripts/postinstall.js +54 -0
- package/src/preflight.js +27 -1
- package/src/status-footer.js +19 -12
- package/task-lib/commands/list.js +90 -78
- package/task-lib/commands/status.js +97 -40
- package/task-lib/effective-status.js +52 -0
package/src/status-footer.js
CHANGED
|
@@ -151,21 +151,29 @@ class StatusFooter {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
|
-
* Print
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* MUST be used instead of console.log() when status footer is active.
|
|
159
|
-
* @param {string} text - Text to print (newline will be added)
|
|
154
|
+
* Print one logical line while coordinating with footer rendering.
|
|
155
|
+
* The caller owns line normalization; this method appends one newline.
|
|
156
|
+
* @param {string} text
|
|
160
157
|
*/
|
|
161
158
|
print(text) {
|
|
159
|
+
this._queueOrWrite(`${text}\n`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Write an exact streaming chunk while coordinating with footer rendering.
|
|
164
|
+
* @param {string} text
|
|
165
|
+
*/
|
|
166
|
+
write(text) {
|
|
167
|
+
this._queueOrWrite(String(text));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** @private */
|
|
171
|
+
_queueOrWrite(text) {
|
|
162
172
|
if (this.isRendering) {
|
|
163
|
-
// Queue for later - render() will flush after restoring cursor
|
|
164
173
|
this.printQueue.push(text);
|
|
165
|
-
|
|
166
|
-
// Write immediately - no render in progress
|
|
167
|
-
process.stdout.write(text + '\n');
|
|
174
|
+
return;
|
|
168
175
|
}
|
|
176
|
+
process.stdout.write(text);
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
/**
|
|
@@ -176,8 +184,7 @@ class StatusFooter {
|
|
|
176
184
|
_flushPrintQueue() {
|
|
177
185
|
if (this.printQueue.length === 0) return;
|
|
178
186
|
|
|
179
|
-
|
|
180
|
-
const output = this.printQueue.map((text) => text + '\n').join('');
|
|
187
|
+
const output = this.printQueue.join('');
|
|
181
188
|
this.printQueue = [];
|
|
182
189
|
process.stdout.write(output);
|
|
183
190
|
}
|
|
@@ -1,97 +1,109 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { resolveEffectiveTaskStatus } from '../effective-status.js';
|
|
2
3
|
import { loadTasks } from '../store.js';
|
|
3
|
-
import { isProcessRunning } from '../runner.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const DEFAULT_LIMIT = 20;
|
|
6
|
+
|
|
7
|
+
function selectTasks(options = {}, deps = {}) {
|
|
8
|
+
const readTasks = deps.loadTasks || loadTasks;
|
|
9
|
+
const resolveStatus = deps.resolveEffectiveTaskStatus || resolveEffectiveTaskStatus;
|
|
10
|
+
const allTasks = Object.values(readTasks());
|
|
11
|
+
const selected = allTasks
|
|
12
|
+
.map((task) => ({ task, effectiveStatus: resolveStatus(task) }))
|
|
13
|
+
.sort((left, right) => new Date(left.task.createdAt) - new Date(right.task.createdAt))
|
|
14
|
+
.filter(({ effectiveStatus }) => !options.status || effectiveStatus.status === options.status)
|
|
15
|
+
.slice(0, options.limit || DEFAULT_LIMIT);
|
|
16
|
+
return { total: allTasks.length, selected };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function projectTask({ task, effectiveStatus }) {
|
|
20
|
+
return {
|
|
21
|
+
id: task.id,
|
|
22
|
+
status: effectiveStatus.status,
|
|
23
|
+
statusReason: effectiveStatus.reason,
|
|
24
|
+
cwd: task.cwd,
|
|
25
|
+
provider: task.provider || null,
|
|
26
|
+
model: task.model || null,
|
|
27
|
+
createdAt: task.createdAt,
|
|
28
|
+
updatedAt: task.updatedAt,
|
|
29
|
+
exitCode: task.exitCode ?? null,
|
|
30
|
+
error: task.error || null,
|
|
31
|
+
attachable: task.attachable === true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getTasksData(options = {}, deps = {}) {
|
|
36
|
+
return selectTasks(options, deps).selected.map(projectTask);
|
|
37
|
+
}
|
|
8
38
|
|
|
9
|
-
|
|
39
|
+
export function listTasks(options = {}, deps = {}) {
|
|
40
|
+
const { selected, total } = selectTasks(options, deps);
|
|
41
|
+
|
|
42
|
+
if (total === 0) {
|
|
10
43
|
console.log(chalk.dim('No tasks found.'));
|
|
11
44
|
return;
|
|
12
45
|
}
|
|
13
46
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let filtered = taskList;
|
|
19
|
-
if (options.status) {
|
|
20
|
-
filtered = taskList.filter((t) => t.status === options.status);
|
|
47
|
+
if (options.verbose) {
|
|
48
|
+
printVerboseTasks(selected, total);
|
|
49
|
+
} else {
|
|
50
|
+
printTaskTable(selected, total);
|
|
21
51
|
}
|
|
52
|
+
}
|
|
22
53
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const statusColor =
|
|
40
|
-
{
|
|
41
|
-
running: chalk.green,
|
|
42
|
-
completed: chalk.green,
|
|
43
|
-
failed: chalk.red,
|
|
44
|
-
stale: chalk.yellow,
|
|
45
|
-
}[status] || chalk.dim;
|
|
46
|
-
|
|
47
|
-
const age = getAge(task.createdAt);
|
|
48
|
-
const timestamp = new Date(task.createdAt).toLocaleString();
|
|
49
|
-
|
|
50
|
-
console.log(
|
|
51
|
-
`${statusColor('●')} ${chalk.cyan(task.id)} ${statusColor(`[${status}]`)} ${chalk.dim(age + ' • ' + timestamp)}`
|
|
52
|
-
);
|
|
53
|
-
console.log(` ${chalk.dim('CWD:')} ${task.cwd}`);
|
|
54
|
-
console.log(` ${chalk.dim('Prompt:')} ${task.prompt}`);
|
|
55
|
-
if (task.pid && status === 'running') {
|
|
56
|
-
console.log(` ${chalk.dim('PID:')} ${task.pid}`);
|
|
57
|
-
}
|
|
58
|
-
if (task.error) {
|
|
59
|
-
console.log(` ${chalk.red('Error:')} ${task.error}`);
|
|
60
|
-
}
|
|
61
|
-
console.log();
|
|
54
|
+
function printVerboseTasks(selected, total) {
|
|
55
|
+
console.log(chalk.bold(`\nTasks (${selected.length}/${total})\n`));
|
|
56
|
+
|
|
57
|
+
for (const { task, effectiveStatus } of selected) {
|
|
58
|
+
const statusColor = colorForStatus(effectiveStatus.status);
|
|
59
|
+
const age = getAge(task.createdAt);
|
|
60
|
+
const timestamp = new Date(task.createdAt).toLocaleString();
|
|
61
|
+
|
|
62
|
+
const heading = `${statusColor('●')} ${chalk.cyan(task.id)}`;
|
|
63
|
+
const status = statusColor(`[${effectiveStatus.status}]`);
|
|
64
|
+
const timing = chalk.dim(age + ' • ' + timestamp);
|
|
65
|
+
console.log(`${heading} ${status} ${timing}`);
|
|
66
|
+
console.log(` ${chalk.dim('CWD:')} ${task.cwd}`);
|
|
67
|
+
console.log(` ${chalk.dim('Prompt:')} ${task.prompt}`);
|
|
68
|
+
if (task.pid && effectiveStatus.status === 'running') {
|
|
69
|
+
console.log(` ${chalk.dim('PID:')} ${task.pid}`);
|
|
62
70
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
console.log(chalk.bold(`\n=== Tasks (${filtered.length}/${taskList.length}) ===`));
|
|
66
|
-
console.log(`${'ID'.padEnd(25)} ${'Status'.padEnd(12)} ${'Age'.padEnd(10)} CWD`);
|
|
67
|
-
console.log('-'.repeat(100));
|
|
68
|
-
|
|
69
|
-
for (const task of filtered) {
|
|
70
|
-
// Verify running status
|
|
71
|
-
let status = task.status;
|
|
72
|
-
if (status === 'running' && !isProcessRunning(task.pid)) {
|
|
73
|
-
status = 'stale';
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const statusColor =
|
|
77
|
-
{
|
|
78
|
-
running: chalk.green,
|
|
79
|
-
completed: chalk.green,
|
|
80
|
-
failed: chalk.red,
|
|
81
|
-
stale: chalk.yellow,
|
|
82
|
-
}[status] || chalk.dim;
|
|
83
|
-
|
|
84
|
-
const age = getAge(task.createdAt);
|
|
85
|
-
const cwd = task.cwd.replace(process.env.HOME, '~');
|
|
86
|
-
|
|
87
|
-
console.log(
|
|
88
|
-
`${chalk.cyan(task.id.padEnd(25))} ${statusColor(status.padEnd(12))} ${chalk.dim(age.padEnd(10))} ${chalk.dim(cwd)}`
|
|
89
|
-
);
|
|
71
|
+
if (task.error) {
|
|
72
|
+
console.log(` ${chalk.red('Error:')} ${task.error}`);
|
|
90
73
|
}
|
|
91
74
|
console.log();
|
|
92
75
|
}
|
|
93
76
|
}
|
|
94
77
|
|
|
78
|
+
function printTaskTable(selected, total) {
|
|
79
|
+
console.log(chalk.bold(`\n=== Tasks (${selected.length}/${total}) ===`));
|
|
80
|
+
console.log(`${'ID'.padEnd(25)} ${'Status'.padEnd(12)} ${'Age'.padEnd(10)} CWD`);
|
|
81
|
+
console.log('-'.repeat(100));
|
|
82
|
+
|
|
83
|
+
for (const { task, effectiveStatus } of selected) {
|
|
84
|
+
const statusColor = colorForStatus(effectiveStatus.status);
|
|
85
|
+
const age = getAge(task.createdAt);
|
|
86
|
+
const cwd = process.env.HOME ? task.cwd.replace(process.env.HOME, '~') : task.cwd;
|
|
87
|
+
|
|
88
|
+
const id = chalk.cyan(task.id.padEnd(25));
|
|
89
|
+
const status = statusColor(effectiveStatus.status.padEnd(12));
|
|
90
|
+
const timing = chalk.dim(age.padEnd(10));
|
|
91
|
+
console.log(`${id} ${status} ${timing} ${chalk.dim(cwd)}`);
|
|
92
|
+
}
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function colorForStatus(status) {
|
|
97
|
+
return (
|
|
98
|
+
{
|
|
99
|
+
running: chalk.green,
|
|
100
|
+
completed: chalk.green,
|
|
101
|
+
failed: chalk.red,
|
|
102
|
+
stale: chalk.yellow,
|
|
103
|
+
}[status] || chalk.dim
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
function getAge(dateStr) {
|
|
96
108
|
const diff = Date.now() - new Date(dateStr).getTime();
|
|
97
109
|
const mins = Math.floor(diff / 60000);
|
|
@@ -1,58 +1,115 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { resolveEffectiveTaskStatus } from '../effective-status.js';
|
|
2
3
|
import { getTask } from '../store.js';
|
|
3
|
-
import { isOwnedProcessTreeRunning } from '../runner.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
function nullable(value) {
|
|
6
|
+
if (value === undefined || value === null || value === '') return null;
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function preferredPrompt(task) {
|
|
11
|
+
const fullPrompt = nullable(task.fullPrompt);
|
|
12
|
+
if (fullPrompt !== null) return fullPrompt;
|
|
13
|
+
return nullable(task.prompt);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function cleanupState(commandCleanup) {
|
|
17
|
+
if (commandCleanup) return 'pending';
|
|
18
|
+
return 'complete';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function projectStatus(task, effectiveStatus) {
|
|
22
|
+
return {
|
|
23
|
+
id: task.id,
|
|
24
|
+
status: effectiveStatus.status,
|
|
25
|
+
statusReason: effectiveStatus.reason,
|
|
26
|
+
statusDetail: effectiveStatus.detail,
|
|
27
|
+
createdAt: task.createdAt,
|
|
28
|
+
updatedAt: task.updatedAt,
|
|
29
|
+
cwd: task.cwd,
|
|
30
|
+
pid: nullable(task.pid),
|
|
31
|
+
exitCode: nullable(task.exitCode),
|
|
32
|
+
sessionId: nullable(task.sessionId),
|
|
33
|
+
requestedResumeSessionId: nullable(task.requestedResumeSessionId),
|
|
34
|
+
cleanup: cleanupState(task.commandCleanup),
|
|
35
|
+
logFile: nullable(task.logFile),
|
|
36
|
+
prompt: preferredPrompt(task),
|
|
37
|
+
error: nullable(task.error),
|
|
38
|
+
provider: nullable(task.provider),
|
|
39
|
+
model: nullable(task.model),
|
|
40
|
+
attachable: task.attachable === true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
7
43
|
|
|
44
|
+
export function getStatusData(taskId, deps = {}) {
|
|
45
|
+
const readTask = deps.getTask || getTask;
|
|
46
|
+
const resolveStatus = deps.resolveEffectiveTaskStatus || resolveEffectiveTaskStatus;
|
|
47
|
+
const task = readTask(taskId);
|
|
8
48
|
if (!task) {
|
|
9
|
-
|
|
10
|
-
process.exit(1);
|
|
49
|
+
throw new Error(`Task not found: ${taskId}`);
|
|
11
50
|
}
|
|
51
|
+
return projectStatus(task, resolveStatus(task));
|
|
52
|
+
}
|
|
12
53
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
if (!running) {
|
|
22
|
-
status = 'stale (process died)';
|
|
23
|
-
}
|
|
24
|
-
} catch (error) {
|
|
25
|
-
status = `stale (invalid process ownership: ${error.message})`;
|
|
26
|
-
}
|
|
54
|
+
function loadStatusOrExit(taskId, deps) {
|
|
55
|
+
try {
|
|
56
|
+
return getStatusData(taskId, deps);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.log(chalk.red(error.message));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
return null;
|
|
27
61
|
}
|
|
62
|
+
}
|
|
28
63
|
|
|
29
|
-
|
|
64
|
+
function colorForStatus(status) {
|
|
65
|
+
return (
|
|
30
66
|
{
|
|
31
67
|
running: chalk.green,
|
|
32
68
|
completed: chalk.green,
|
|
33
69
|
failed: chalk.red,
|
|
34
|
-
}[
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.log(`${chalk.dim('Status:')} ${statusColor(status)}`);
|
|
38
|
-
console.log(`${chalk.dim('Created:')} ${task.createdAt}`);
|
|
39
|
-
console.log(`${chalk.dim('Updated:')} ${task.updatedAt}`);
|
|
40
|
-
console.log(`${chalk.dim('CWD:')} ${task.cwd}`);
|
|
41
|
-
console.log(`${chalk.dim('PID:')} ${task.pid || 'N/A'}`);
|
|
42
|
-
console.log(`${chalk.dim('Exit Code:')} ${task.exitCode ?? 'N/A'}`);
|
|
43
|
-
console.log(`${chalk.dim('Session:')} ${task.sessionId || 'N/A'}`);
|
|
44
|
-
console.log(`${chalk.dim('Cleanup:')} ${task.commandCleanup ? 'pending' : 'complete'}`);
|
|
45
|
-
if (task.requestedResumeSessionId) {
|
|
46
|
-
console.log(`${chalk.dim('Requested:')} ${task.requestedResumeSessionId}`);
|
|
47
|
-
}
|
|
48
|
-
console.log(`${chalk.dim('Log File:')} ${task.logFile}`);
|
|
70
|
+
}[status] || chalk.yellow
|
|
71
|
+
);
|
|
72
|
+
}
|
|
49
73
|
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
function statusLabel(status) {
|
|
75
|
+
if (status.statusDetail) return `${status.status} (${status.statusDetail})`;
|
|
76
|
+
return status.status;
|
|
77
|
+
}
|
|
52
78
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
function displayOptional(value) {
|
|
80
|
+
if (value === null) return 'N/A';
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function printRequestedSession(status) {
|
|
85
|
+
if (!status.requestedResumeSessionId) return;
|
|
86
|
+
console.log(`${chalk.dim('Requested:')} ${status.requestedResumeSessionId}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function printError(status) {
|
|
90
|
+
if (!status.error) return;
|
|
91
|
+
console.log(`\n${chalk.red('Error:')} ${status.error}`);
|
|
92
|
+
}
|
|
56
93
|
|
|
94
|
+
export function showStatus(taskId, deps = {}) {
|
|
95
|
+
const status = loadStatusOrExit(taskId, deps);
|
|
96
|
+
if (!status) return;
|
|
97
|
+
|
|
98
|
+
const statusColor = colorForStatus(status.status);
|
|
99
|
+
console.log(chalk.bold(`\nTask: ${status.id}\n`));
|
|
100
|
+
console.log(`${chalk.dim('Status:')} ${statusColor(statusLabel(status))}`);
|
|
101
|
+
console.log(`${chalk.dim('Created:')} ${status.createdAt}`);
|
|
102
|
+
console.log(`${chalk.dim('Updated:')} ${status.updatedAt}`);
|
|
103
|
+
console.log(`${chalk.dim('CWD:')} ${status.cwd}`);
|
|
104
|
+
console.log(`${chalk.dim('PID:')} ${displayOptional(status.pid)}`);
|
|
105
|
+
console.log(`${chalk.dim('Exit Code:')} ${displayOptional(status.exitCode)}`);
|
|
106
|
+
console.log(`${chalk.dim('Session:')} ${displayOptional(status.sessionId)}`);
|
|
107
|
+
console.log(`${chalk.dim('Cleanup:')} ${status.cleanup}`);
|
|
108
|
+
printRequestedSession(status);
|
|
109
|
+
console.log(`${chalk.dim('Log File:')} ${displayOptional(status.logFile)}`);
|
|
110
|
+
|
|
111
|
+
console.log(`\n${chalk.dim('Prompt:')}`);
|
|
112
|
+
console.log(displayOptional(status.prompt));
|
|
113
|
+
printError(status);
|
|
57
114
|
console.log();
|
|
58
115
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { isOwnedProcessTreeRunning } from './runner.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_STARTUP_GRACE_MS = 30_000;
|
|
4
|
+
|
|
5
|
+
const STALE_REASON_LABELS = {
|
|
6
|
+
invalid_process_ownership: 'invalid process ownership',
|
|
7
|
+
process_died: 'process died',
|
|
8
|
+
startup_timeout: 'provider startup timed out',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function runningStatus() {
|
|
12
|
+
return { status: 'running', reason: null, detail: null, label: 'running' };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function staleStatus(reason) {
|
|
16
|
+
const detail = STALE_REASON_LABELS[reason];
|
|
17
|
+
return { status: 'stale', reason, detail, label: `stale (${detail})` };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function resolveStartupStatus(task, deps) {
|
|
21
|
+
const createdAt = Date.parse(task.createdAt);
|
|
22
|
+
const now = deps.now?.() ?? Date.now();
|
|
23
|
+
const graceMs = deps.startupGraceMs ?? DEFAULT_STARTUP_GRACE_MS;
|
|
24
|
+
return Number.isFinite(createdAt) && now >= createdAt && now - createdAt <= graceMs
|
|
25
|
+
? runningStatus()
|
|
26
|
+
: staleStatus('startup_timeout');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function resolveEffectiveTaskStatus(task, deps = {}) {
|
|
30
|
+
if (task.status !== 'running') {
|
|
31
|
+
return { status: task.status, reason: null, detail: null, label: task.status };
|
|
32
|
+
}
|
|
33
|
+
// The durable row is written before the detached watcher can publish its owned provider PID.
|
|
34
|
+
// Treat that startup window as live, but bound it so an abandoned watcher cannot look active
|
|
35
|
+
// indefinitely.
|
|
36
|
+
if (task.pid === null) return resolveStartupStatus(task, deps);
|
|
37
|
+
|
|
38
|
+
const isRunning = deps.isOwnedProcessTreeRunning || isOwnedProcessTreeRunning;
|
|
39
|
+
try {
|
|
40
|
+
if (
|
|
41
|
+
isRunning(task.pid, {
|
|
42
|
+
processGroupId: task.processGroupId,
|
|
43
|
+
terminationStrategy: task.terminationStrategy || 'process',
|
|
44
|
+
})
|
|
45
|
+
) {
|
|
46
|
+
return runningStatus();
|
|
47
|
+
}
|
|
48
|
+
return staleStatus('process_died');
|
|
49
|
+
} catch {
|
|
50
|
+
return staleStatus('invalid_process_ownership');
|
|
51
|
+
}
|
|
52
|
+
}
|