@crewx/cli 0.9.0-rc.95 → 0.9.0-rc.97
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/commands/cal.d.ts +12 -0
- package/dist/commands/cal.js +34 -0
- package/dist/commands/detached.js +2 -1
- package/dist/commands/result.d.ts +2 -1
- package/dist/commands/result.js +40 -10
- package/package.json +13 -13
package/dist/commands/cal.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
import type { ActionContext } from '@crewx/knowledge-core';
|
|
2
|
+
/** Suggested wait rungs in seconds. 540 is the safe caller-harness cap. */
|
|
3
|
+
export declare const WAIT_LADDER_SECONDS: readonly [60, 300, 540];
|
|
4
|
+
export interface SuggestWaitSecondsOptions {
|
|
5
|
+
startedAt?: string | number | Date | null;
|
|
6
|
+
lastWaitSeconds?: number;
|
|
7
|
+
now?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Select the next safe result wait based on task runtime without stepping
|
|
11
|
+
* down from the wait value the caller just used.
|
|
12
|
+
*/
|
|
13
|
+
export declare function suggestWaitSeconds(options: SuggestWaitSecondsOptions): number;
|
|
2
14
|
/** Write a human-only CAL footer without contaminating command stdout. */
|
|
3
15
|
export declare function writeCalFooter(context: ActionContext): void;
|
package/dist/commands/cal.js
CHANGED
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WAIT_LADDER_SECONDS = void 0;
|
|
4
|
+
exports.suggestWaitSeconds = suggestWaitSeconds;
|
|
3
5
|
exports.writeCalFooter = writeCalFooter;
|
|
4
6
|
const knowledge_core_1 = require("@crewx/knowledge-core");
|
|
7
|
+
/** Suggested wait rungs in seconds. 540 is the safe caller-harness cap. */
|
|
8
|
+
exports.WAIT_LADDER_SECONDS = [60, 300, 540];
|
|
9
|
+
function toTimestamp(value) {
|
|
10
|
+
if (value instanceof Date) {
|
|
11
|
+
return Number.isFinite(value.getTime()) ? value.getTime() : undefined;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === 'number') {
|
|
14
|
+
return Number.isFinite(value) ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
|
+
const timestamp = Date.parse(value);
|
|
18
|
+
return Number.isFinite(timestamp) ? timestamp : undefined;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Select the next safe result wait based on task runtime without stepping
|
|
24
|
+
* down from the wait value the caller just used.
|
|
25
|
+
*/
|
|
26
|
+
function suggestWaitSeconds(options) {
|
|
27
|
+
const now = Number.isFinite(options.now) ? options.now : Date.now();
|
|
28
|
+
const startedAt = toTimestamp(options.startedAt);
|
|
29
|
+
const elapsedSeconds = startedAt === undefined
|
|
30
|
+
? 0
|
|
31
|
+
: Math.max(0, (now - startedAt) / 1000);
|
|
32
|
+
const rung = exports.WAIT_LADDER_SECONDS.find(seconds => seconds > elapsedSeconds)
|
|
33
|
+
?? exports.WAIT_LADDER_SECONDS[exports.WAIT_LADDER_SECONDS.length - 1];
|
|
34
|
+
const lastWaitSeconds = Number.isFinite(options.lastWaitSeconds)
|
|
35
|
+
? Math.max(0, options.lastWaitSeconds)
|
|
36
|
+
: 0;
|
|
37
|
+
return Math.min(exports.WAIT_LADDER_SECONDS[exports.WAIT_LADDER_SECONDS.length - 1], Math.max(rung, lastWaitSeconds));
|
|
38
|
+
}
|
|
5
39
|
/** Write a human-only CAL footer without contaminating command stdout. */
|
|
6
40
|
function writeCalFooter(context) {
|
|
7
41
|
const block = (0, knowledge_core_1.formatActions)((0, knowledge_core_1.generateNextActions)(context));
|
|
@@ -190,9 +190,10 @@ function announceDetachedTask(taskRepo, taskId, logPath, reason, verbose, output
|
|
|
190
190
|
process.stderr.write(`Task ${taskId} accepted. This ID is the handle (not a PID).\n`);
|
|
191
191
|
if (warning && verbose)
|
|
192
192
|
process.stderr.write(`${warning}\n`);
|
|
193
|
+
const waitSeconds = (0, cal_1.suggestWaitSeconds)({ startedAt: null });
|
|
193
194
|
(0, cal_1.writeCalFooter)({
|
|
194
195
|
commandId: 'crewx.receipt',
|
|
195
|
-
params: { taskId },
|
|
196
|
+
params: { taskId, wait: String(waitSeconds) },
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
/**
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Usage:
|
|
6
6
|
* crewx result <task-id> Print raw result
|
|
7
7
|
* crewx result <task-id> --json Print full task record as JSON
|
|
8
|
-
* crewx result <task-id> --wait
|
|
8
|
+
* crewx result <task-id> --wait=<seconds> Poll (1s interval) up to the given
|
|
9
|
+
* number of seconds for
|
|
9
10
|
* the task to leave 'pending'/'running'. Exit 124 on
|
|
10
11
|
* timeout. --wait=0 behaves like no --wait
|
|
11
12
|
* (single immediate check).
|
package/dist/commands/result.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* Usage:
|
|
7
7
|
* crewx result <task-id> Print raw result
|
|
8
8
|
* crewx result <task-id> --json Print full task record as JSON
|
|
9
|
-
* crewx result <task-id> --wait
|
|
9
|
+
* crewx result <task-id> --wait=<seconds> Poll (1s interval) up to the given
|
|
10
|
+
* number of seconds for
|
|
10
11
|
* the task to leave 'pending'/'running'. Exit 124 on
|
|
11
12
|
* timeout. --wait=0 behaves like no --wait
|
|
12
13
|
* (single immediate check).
|
|
@@ -48,15 +49,35 @@ function resultCommandId(status) {
|
|
|
48
49
|
default: return 'crewx.result';
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
function writeResultCalFooter(task) {
|
|
52
|
+
function writeResultCalFooter(task, lastWaitSeconds) {
|
|
52
53
|
const params = { taskId: task.id };
|
|
53
54
|
if (task.agent_id)
|
|
54
55
|
params.agent = task.agent_id;
|
|
55
56
|
if (task.thread_id)
|
|
56
57
|
params.thread = task.thread_id;
|
|
58
|
+
if (isActiveStatus(task.status)) {
|
|
59
|
+
params.wait = String((0, cal_1.suggestWaitSeconds)({
|
|
60
|
+
startedAt: task.started_at,
|
|
61
|
+
lastWaitSeconds,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
57
64
|
(0, cal_1.writeCalFooter)({ commandId: resultCommandId(task.status), params });
|
|
58
65
|
}
|
|
59
|
-
|
|
66
|
+
function formatRuntimeDuration(startedAt, now = Date.now()) {
|
|
67
|
+
const startedAtMs = Date.parse(startedAt);
|
|
68
|
+
const elapsedSeconds = Number.isFinite(startedAtMs)
|
|
69
|
+
? Math.max(0, Math.floor((now - startedAtMs) / 1000))
|
|
70
|
+
: 0;
|
|
71
|
+
const hours = Math.floor(elapsedSeconds / 3600);
|
|
72
|
+
const minutes = Math.floor((elapsedSeconds % 3600) / 60);
|
|
73
|
+
const seconds = elapsedSeconds % 60;
|
|
74
|
+
if (hours > 0)
|
|
75
|
+
return `${hours}h ${minutes}m ${seconds}s`;
|
|
76
|
+
if (minutes > 0)
|
|
77
|
+
return `${minutes}m ${seconds}s`;
|
|
78
|
+
return `${seconds}s`;
|
|
79
|
+
}
|
|
80
|
+
/** Parses `--wait=<seconds>`. Returns undefined when the flag is absent. */
|
|
60
81
|
function parseWaitSeconds(args) {
|
|
61
82
|
const arg = args.find(a => a.startsWith('--wait='));
|
|
62
83
|
if (arg === undefined)
|
|
@@ -107,9 +128,10 @@ async function handleResult(args) {
|
|
|
107
128
|
let lastReapAt = Date.now();
|
|
108
129
|
while (task && isActiveStatus(task.status)) {
|
|
109
130
|
if (Date.now() >= deadline) {
|
|
110
|
-
console.error(`Task ${taskId} is still ${task.status} (waited ${waitSeconds}s;
|
|
111
|
-
|
|
112
|
-
|
|
131
|
+
console.error(`Task ${taskId} is still ${task.status} (waited ${waitSeconds}s; ` +
|
|
132
|
+
`running for ${formatRuntimeDuration(task.started_at)}). ` +
|
|
133
|
+
'Not stalled — check again with a longer wait.');
|
|
134
|
+
writeResultCalFooter(task, waitSeconds);
|
|
113
135
|
process.exit(124);
|
|
114
136
|
return;
|
|
115
137
|
}
|
|
@@ -134,15 +156,23 @@ async function handleResult(args) {
|
|
|
134
156
|
}
|
|
135
157
|
if (task.status === 'pending') {
|
|
136
158
|
console.error(`🕓 Task ${taskId} is pending (waiting to start — runner has not adopted the task yet).`);
|
|
137
|
-
|
|
138
|
-
|
|
159
|
+
const nextWaitSeconds = (0, cal_1.suggestWaitSeconds)({
|
|
160
|
+
startedAt: task.started_at,
|
|
161
|
+
lastWaitSeconds: waitSeconds,
|
|
162
|
+
});
|
|
163
|
+
console.error(`Use \`crewx result ${taskId} --wait=${nextWaitSeconds}\` to wait for completion.`);
|
|
164
|
+
writeResultCalFooter(task, waitSeconds);
|
|
139
165
|
process.exit(1);
|
|
140
166
|
return;
|
|
141
167
|
}
|
|
142
168
|
if (task.status === 'running') {
|
|
143
169
|
console.error(`Task ${taskId} is still running.`);
|
|
144
|
-
|
|
145
|
-
|
|
170
|
+
const nextWaitSeconds = (0, cal_1.suggestWaitSeconds)({
|
|
171
|
+
startedAt: task.started_at,
|
|
172
|
+
lastWaitSeconds: waitSeconds,
|
|
173
|
+
});
|
|
174
|
+
console.error(`Use \`crewx result ${taskId} --wait=${nextWaitSeconds}\` to wait longer or \`crewx log ${taskId}\` to inspect progress.`);
|
|
175
|
+
writeResultCalFooter(task, waitSeconds);
|
|
146
176
|
process.exit(1);
|
|
147
177
|
return;
|
|
148
178
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewx/cli",
|
|
3
|
-
"version": "0.9.0-rc.
|
|
3
|
+
"version": "0.9.0-rc.97",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.19.0"
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
"better-sqlite3": "*",
|
|
26
26
|
"dotenv": "17.2.3",
|
|
27
27
|
"isomorphic-git": "1.37.1",
|
|
28
|
-
"@crewx/sdk": "0.9.0-rc.
|
|
29
|
-
"@crewx/
|
|
30
|
-
"@crewx/search": "0.1.10-rc.
|
|
31
|
-
"@crewx/doc": "0.1.9-rc.
|
|
32
|
-
"@crewx/
|
|
33
|
-
"@crewx/
|
|
34
|
-
"@crewx/workflow": "0.3.22-rc.
|
|
28
|
+
"@crewx/sdk": "0.9.0-rc.97",
|
|
29
|
+
"@crewx/knowledge-core": "0.1.17-rc.107",
|
|
30
|
+
"@crewx/search": "0.1.10-rc.93",
|
|
31
|
+
"@crewx/doc": "0.1.9-rc.90",
|
|
32
|
+
"@crewx/memory": "0.1.23-rc.114",
|
|
33
|
+
"@crewx/cron": "0.1.10-rc.132",
|
|
34
|
+
"@crewx/workflow": "0.3.22-rc.143",
|
|
35
35
|
"@crewx/skill": "0.1.20",
|
|
36
|
-
"@crewx/
|
|
37
|
-
"@crewx/
|
|
38
|
-
"@crewx/
|
|
39
|
-
"@crewx/
|
|
40
|
-
"@crewx/
|
|
36
|
+
"@crewx/chromex": "0.1.0-rc.130",
|
|
37
|
+
"@crewx/wi": "0.1.10-rc.117",
|
|
38
|
+
"@crewx/wbs": "0.1.10-rc.123",
|
|
39
|
+
"@crewx/notify": "0.1.0-rc.68",
|
|
40
|
+
"@crewx/shared": "0.0.6"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/better-sqlite3": "*",
|