@the-open-engine/zeroshot 6.31.3 → 6.32.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 +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/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +8 -2
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/agent-cli-provider/provider-registry.d.ts +4 -2
- package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
- package/lib/agent-cli-provider/provider-registry.js +13 -3
- package/lib/agent-cli-provider/provider-registry.js.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.js +7 -4
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
- package/lib/agent-cli-provider/types.d.ts +2 -0
- package/lib/agent-cli-provider/types.d.ts.map +1 -1
- package/lib/agent-cli-provider/types.js.map +1 -1
- 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 +3 -3
- package/scripts/postinstall.js +54 -0
- package/src/agent/agent-lifecycle.js +11 -1
- package/src/agent/agent-task-executor.js +25 -7
- package/src/agent/structured-output-error.js +42 -0
- package/src/agent-cli-provider/adapters/codex.ts +8 -12
- package/src/agent-cli-provider/provider-registry.ts +15 -3
- package/src/agent-cli-provider/single-agent-runtime.ts +11 -11
- package/src/agent-cli-provider/types.ts +2 -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
|
@@ -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
|
+
}
|