@crewx/cli 0.9.0-rc.6 → 0.9.0-rc.60
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/bootstrap/codex-writable-roots.d.ts +45 -0
- package/dist/bootstrap/codex-writable-roots.js +88 -0
- package/dist/bootstrap/crewx-cli.js +2 -0
- package/dist/builtin.js +1 -0
- package/dist/commands/doctor.d.ts +17 -0
- package/dist/commands/doctor.js +21 -11
- package/dist/commands/execute.d.ts +4 -0
- package/dist/commands/execute.js +107 -3
- package/dist/commands/init.js +22 -1
- package/dist/commands/log.js +4 -3
- package/dist/commands/parse-common-flags.d.ts +8 -2
- package/dist/commands/parse-common-flags.js +12 -3
- package/dist/commands/ps.js +51 -2
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.js +270 -0
- package/dist/commands/query.d.ts +1 -0
- package/dist/commands/query.js +15 -2
- package/dist/commands/registry.js +3 -1
- package/dist/commands/restart.js +20 -6
- package/dist/commands/result.d.ts +7 -3
- package/dist/commands/result.js +41 -6
- package/dist/commands/shortcut.d.ts +1 -0
- package/dist/commands/shortcut.js +267 -0
- package/dist/commands/slack.js +2 -1
- package/dist/commands/write-output.d.ts +3 -0
- package/dist/commands/write-output.js +24 -0
- package/dist/logging.d.ts +1 -1
- package/dist/logging.js +3 -2
- package/dist/main.d.ts +3 -2
- package/dist/main.js +45 -7
- package/dist/utils/env-defaults.d.ts +2 -5
- package/dist/utils/env-defaults.js +10 -5
- package/dist/utils/sdk-compat.d.ts +21 -0
- package/dist/utils/sdk-compat.js +72 -0
- package/package.json +12 -10
package/dist/commands/ps.js
CHANGED
|
@@ -21,14 +21,54 @@ function formatElapsed(ms) {
|
|
|
21
21
|
const h = Math.floor(m / 60);
|
|
22
22
|
return `${h}h ${m % 60}m`;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Antigravity-family providers (coding_agent_command starting with 'agy',
|
|
26
|
+
* path-included forms like '/usr/local/bin/agy' also count) don't emit
|
|
27
|
+
* parseable logs, so they get a distinct 'n/a' instead of '—'.
|
|
28
|
+
*/
|
|
29
|
+
function isAgyCommand(codingAgentCommand) {
|
|
30
|
+
const cmd = (codingAgentCommand ?? '').trim();
|
|
31
|
+
if (!cmd)
|
|
32
|
+
return false;
|
|
33
|
+
const firstToken = cmd.split(/\s+/)[0] ?? '';
|
|
34
|
+
const base = firstToken.split('/').pop() ?? firstToken;
|
|
35
|
+
return base.startsWith('agy');
|
|
36
|
+
}
|
|
37
|
+
function getLastActive(task) {
|
|
38
|
+
try {
|
|
39
|
+
const entries = task.logs ? JSON.parse(task.logs) : [];
|
|
40
|
+
if (Array.isArray(entries) && entries.length > 0) {
|
|
41
|
+
const lastEntry = entries[entries.length - 1];
|
|
42
|
+
const ts = lastEntry?.timestamp;
|
|
43
|
+
const parsedMs = ts ? new Date(ts).getTime() : NaN;
|
|
44
|
+
if (ts && !Number.isNaN(parsedMs)) {
|
|
45
|
+
const diffMs = Math.max(0, Date.now() - parsedMs);
|
|
46
|
+
return {
|
|
47
|
+
display: `${formatElapsed(diffMs)} ago`,
|
|
48
|
+
isoTimestamp: ts,
|
|
49
|
+
logCapable: true,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// fall through to antigravity/dash fallback below
|
|
56
|
+
}
|
|
57
|
+
if (isAgyCommand(task.coding_agent_command)) {
|
|
58
|
+
return { display: 'n/a', isoTimestamp: null, logCapable: false };
|
|
59
|
+
}
|
|
60
|
+
return { display: '—', isoTimestamp: null, logCapable: true };
|
|
61
|
+
}
|
|
24
62
|
function taskToRow(task) {
|
|
25
63
|
const elapsed = formatElapsed(Date.now() - new Date(task.started_at).getTime());
|
|
64
|
+
const lastActive = getLastActive(task);
|
|
26
65
|
return [
|
|
27
66
|
task.id,
|
|
28
67
|
task.agent_id ?? '—',
|
|
29
68
|
task.pid !== null && task.pid !== undefined ? String(task.pid) : '—',
|
|
30
69
|
elapsed,
|
|
31
70
|
task.mode ?? '—',
|
|
71
|
+
lastActive.display,
|
|
32
72
|
];
|
|
33
73
|
}
|
|
34
74
|
function renderTable(headers, rows) {
|
|
@@ -43,16 +83,25 @@ function renderTable(headers, rows) {
|
|
|
43
83
|
}
|
|
44
84
|
async function handlePs(args) {
|
|
45
85
|
const repo = new repository_1.TaskRepository();
|
|
86
|
+
repo.reapRunningWorkflowTasks();
|
|
46
87
|
const tasks = repo.getRunningTasks();
|
|
47
88
|
if (tasks.length === 0) {
|
|
48
89
|
console.log('No running tasks.');
|
|
49
90
|
return;
|
|
50
91
|
}
|
|
51
92
|
if (args.includes('--json')) {
|
|
52
|
-
|
|
93
|
+
const withLastActive = tasks.map((task) => {
|
|
94
|
+
const lastActive = getLastActive(task);
|
|
95
|
+
return {
|
|
96
|
+
...task,
|
|
97
|
+
last_active_at: lastActive.isoTimestamp,
|
|
98
|
+
log_capable: lastActive.logCapable,
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
console.log(JSON.stringify(withLastActive, null, 2));
|
|
53
102
|
return;
|
|
54
103
|
}
|
|
55
|
-
const headers = ['TASK ID', 'AGENT', 'PID', 'ELAPSED', 'MODE'];
|
|
104
|
+
const headers = ['TASK ID', 'AGENT', 'PID', 'ELAPSED', 'MODE', 'LAST ACTIVE'];
|
|
56
105
|
const rows = tasks.map(taskToRow);
|
|
57
106
|
renderTable(headers, rows);
|
|
58
107
|
console.log(`\n ${tasks.length} running task(s)`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handlePublish(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handlePublish = handlePublish;
|
|
37
|
+
/**
|
|
38
|
+
* crewx publish handler — thin CLI wrapper over @crewx/sdk/publish.
|
|
39
|
+
*
|
|
40
|
+
* Usage:
|
|
41
|
+
* crewx publish [dir] [--dry-run] [--version <semver>] [--json] [--upload]
|
|
42
|
+
*
|
|
43
|
+
* All scanning, exclusion-rule judgment, secret detection, hashing, and
|
|
44
|
+
* tar.gz packing lives in @crewx/sdk/publish (planPublish / packTemplate).
|
|
45
|
+
* Submit+upload (WI-SHR-20260806-013) lives in the same package
|
|
46
|
+
* (uploadToMarketplace) for the same reason — see that module's header.
|
|
47
|
+
* This command only parses argv, forwards options, reads auth.json
|
|
48
|
+
* (read-only — see readAuthJson()'s own doc), and renders the result.
|
|
49
|
+
*/
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const publish_1 = require("@crewx/sdk/publish");
|
|
52
|
+
const parse_common_flags_1 = require("./parse-common-flags");
|
|
53
|
+
function parsePublishFlags(args) {
|
|
54
|
+
const flags = { dryRun: false, json: false, help: false, upload: false };
|
|
55
|
+
for (let i = 0; i < args.length; i++) {
|
|
56
|
+
const arg = args[i];
|
|
57
|
+
if (arg === '--help' || arg === '-h') {
|
|
58
|
+
flags.help = true;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (arg === '--dry-run') {
|
|
62
|
+
flags.dryRun = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (arg === '--json') {
|
|
66
|
+
flags.json = true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (arg === '--upload') {
|
|
70
|
+
flags.upload = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (arg === '--version') {
|
|
74
|
+
const value = args[i + 1];
|
|
75
|
+
if (value === undefined)
|
|
76
|
+
throw new parse_common_flags_1.UnknownOptionError('--version requires a value');
|
|
77
|
+
flags.version = value;
|
|
78
|
+
i++;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (arg.startsWith('--version=')) {
|
|
82
|
+
flags.version = arg.slice('--version='.length);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (arg.startsWith('-')) {
|
|
86
|
+
throw new parse_common_flags_1.UnknownOptionError(`Unknown option: ${arg}`);
|
|
87
|
+
}
|
|
88
|
+
if (flags.dir === undefined) {
|
|
89
|
+
flags.dir = arg;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
throw new parse_common_flags_1.UnknownOptionError(`Unknown option: ${arg}`);
|
|
93
|
+
}
|
|
94
|
+
return flags;
|
|
95
|
+
}
|
|
96
|
+
function resolveWorkspaceDir(flags) {
|
|
97
|
+
return flags.dir ?? process.env['CREWX_WORKSPACE'] ?? process.cwd();
|
|
98
|
+
}
|
|
99
|
+
function printJson(payload) {
|
|
100
|
+
console.log(JSON.stringify(payload));
|
|
101
|
+
}
|
|
102
|
+
/** Prints the error and exits 1. Never returns (matches `process.exit`'s `never` type). */
|
|
103
|
+
function failWithError(err, json) {
|
|
104
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
105
|
+
if (json) {
|
|
106
|
+
printJson({ success: false, error: message });
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
console.error(`✗ ${message}`);
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
function printHelp() {
|
|
114
|
+
console.log(`
|
|
115
|
+
crewx publish — package a workspace as a distributable template archive
|
|
116
|
+
|
|
117
|
+
Usage:
|
|
118
|
+
crewx publish [dir] [--dry-run] [--version <semver>] [--json] [--upload]
|
|
119
|
+
|
|
120
|
+
Arguments:
|
|
121
|
+
dir Workspace to publish (default: $CREWX_WORKSPACE or cwd)
|
|
122
|
+
|
|
123
|
+
Options:
|
|
124
|
+
--dry-run Scan + build manifest only; do not write a .tgz
|
|
125
|
+
--version <ver> Override manifest version (semver, e.g. 1.0.0)
|
|
126
|
+
--json Print machine-readable JSON to stdout
|
|
127
|
+
--upload Submit + upload the packed archive to marketplace
|
|
128
|
+
(requires CREWX_MARKETPLACE_URL and a prior login;
|
|
129
|
+
ignored when combined with --dry-run)
|
|
130
|
+
--help, -h Show this help
|
|
131
|
+
|
|
132
|
+
Notes:
|
|
133
|
+
Without --upload, this command only scans the workspace, applies
|
|
134
|
+
exclusion rules, checks for secrets, and packs a local
|
|
135
|
+
.crewx/publish/<name>-<version>.tgz archive.
|
|
136
|
+
`.trim());
|
|
137
|
+
}
|
|
138
|
+
/** CREWX_MARKETPLACE_URL — same env var name as the server's MARKETPLACE_DISABLED check, never a second name. */
|
|
139
|
+
function requireMarketplaceUrl() {
|
|
140
|
+
const url = process.env['CREWX_MARKETPLACE_URL'];
|
|
141
|
+
if (!url) {
|
|
142
|
+
throw new Error('publish: [E_ENV_MISSING] CREWX_MARKETPLACE_URL is not set — this environment variable is required for upload');
|
|
143
|
+
}
|
|
144
|
+
return url;
|
|
145
|
+
}
|
|
146
|
+
async function handlePublish(args) {
|
|
147
|
+
const flags = parsePublishFlags(args);
|
|
148
|
+
if (flags.help) {
|
|
149
|
+
printHelp();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const dir = resolveWorkspaceDir(flags);
|
|
153
|
+
process.stderr.write(`[publish] scanning ${dir}...\n`);
|
|
154
|
+
let plan;
|
|
155
|
+
try {
|
|
156
|
+
plan = await (0, publish_1.planPublish)(dir, { version: flags.version });
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
failWithError(err, flags.json);
|
|
160
|
+
}
|
|
161
|
+
if (plan.secretFindings.length > 0) {
|
|
162
|
+
if (flags.json) {
|
|
163
|
+
printJson({ success: false, error: 'secret findings detected', findings: plan.secretFindings });
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.error('✗ secret findings detected — publish aborted');
|
|
167
|
+
for (const f of plan.secretFindings) {
|
|
168
|
+
console.error(` ${f.path}:${f.line} (${f.rule})`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
if (flags.dryRun) {
|
|
174
|
+
if (flags.json) {
|
|
175
|
+
printJson({
|
|
176
|
+
success: true,
|
|
177
|
+
dryRun: true,
|
|
178
|
+
workspace: dir,
|
|
179
|
+
manifest: plan.manifest,
|
|
180
|
+
included: plan.included,
|
|
181
|
+
excluded: plan.excluded,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
console.log('✓ dry-run — no archive written');
|
|
186
|
+
console.log(` workspace: ${dir}`);
|
|
187
|
+
console.log(` name: ${plan.manifest.name} version: ${plan.manifest.version}`);
|
|
188
|
+
console.log(` included: ${plan.included.length} files`);
|
|
189
|
+
console.log(` excluded: ${plan.excluded.length} entries`);
|
|
190
|
+
for (const e of plan.excluded) {
|
|
191
|
+
console.log(` ${e.path} (${e.rule})`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// Resolved before packing (not after) so a doomed --upload run (no
|
|
197
|
+
// marketplace url / no session) never writes a stray .tgz to the
|
|
198
|
+
// workspace — WI-SHR-20260806-013 AC-U5.
|
|
199
|
+
let marketplaceUrl = '';
|
|
200
|
+
let accessToken = '';
|
|
201
|
+
if (flags.upload) {
|
|
202
|
+
try {
|
|
203
|
+
marketplaceUrl = requireMarketplaceUrl();
|
|
204
|
+
accessToken = (0, publish_1.readAuthJson)().access_token;
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
if (err instanceof Error && !err.message.startsWith('publish: [')) {
|
|
208
|
+
failWithError(new Error(`publish: [E_AUTH_EXPIRED] Authentication is missing or expired — please log in again — ${err.message}`), flags.json);
|
|
209
|
+
}
|
|
210
|
+
failWithError(err, flags.json);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
process.stderr.write(`[publish] packing ${plan.manifest.name}@${plan.manifest.version}...\n`);
|
|
214
|
+
let packed;
|
|
215
|
+
try {
|
|
216
|
+
packed = await (0, publish_1.packTemplate)(dir, { version: flags.version });
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
failWithError(err, flags.json);
|
|
220
|
+
}
|
|
221
|
+
const fileCount = packed.manifest.files.length;
|
|
222
|
+
const totalBytes = fs.statSync(packed.tgzPath).size;
|
|
223
|
+
let uploadResult;
|
|
224
|
+
if (flags.upload) {
|
|
225
|
+
process.stderr.write(`[publish] uploading ${packed.manifest.name}@${packed.manifest.version} to ${marketplaceUrl}...\n`);
|
|
226
|
+
try {
|
|
227
|
+
uploadResult = await (0, publish_1.uploadToMarketplace)({
|
|
228
|
+
tgzPath: packed.tgzPath,
|
|
229
|
+
manifest: packed.manifest,
|
|
230
|
+
baseUrl: marketplaceUrl,
|
|
231
|
+
accessToken,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
failWithError(err, flags.json);
|
|
236
|
+
}
|
|
237
|
+
process.stderr.write(`[publish] submit -> ${uploadResult.submitOutcome}\n`);
|
|
238
|
+
}
|
|
239
|
+
if (flags.json) {
|
|
240
|
+
printJson({
|
|
241
|
+
success: true,
|
|
242
|
+
tgzPath: packed.tgzPath,
|
|
243
|
+
fileCount,
|
|
244
|
+
totalBytes,
|
|
245
|
+
manifest: packed.manifest,
|
|
246
|
+
...(uploadResult
|
|
247
|
+
? {
|
|
248
|
+
slug: uploadResult.slug,
|
|
249
|
+
version: uploadResult.version,
|
|
250
|
+
artifactChecksum: uploadResult.artifactChecksum,
|
|
251
|
+
artifactSizeBytes: uploadResult.artifactSizeBytes,
|
|
252
|
+
submitOutcome: uploadResult.submitOutcome,
|
|
253
|
+
versionUpdate: uploadResult.versionUpdate,
|
|
254
|
+
serverVersionBefore: uploadResult.serverVersionBefore,
|
|
255
|
+
}
|
|
256
|
+
: {}),
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
console.log(`✓ packed: ${packed.tgzPath}`);
|
|
261
|
+
console.log(` files: ${fileCount} bytes: ${totalBytes}`);
|
|
262
|
+
if (uploadResult) {
|
|
263
|
+
console.log(`✓ uploaded: ${uploadResult.slug}@${uploadResult.version} (${uploadResult.submitOutcome})`);
|
|
264
|
+
console.log(` artifactChecksum: ${uploadResult.artifactChecksum} artifactSizeBytes: ${uploadResult.artifactSizeBytes}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (!flags.upload) {
|
|
268
|
+
console.error('⚠ To upload, use --upload — check the generated file path');
|
|
269
|
+
}
|
|
270
|
+
}
|
package/dist/commands/query.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Flags:
|
|
6
6
|
* --thread <name> Conversation thread name
|
|
7
7
|
* --provider <cli/xxx> Provider override
|
|
8
|
+
* --model <name> Model override (e.g. claude-sonnet-5)
|
|
8
9
|
* --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
|
|
9
10
|
* e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
10
11
|
* --verbose Debug output mode (default: raw agent response only)
|
package/dist/commands/query.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Flags:
|
|
7
7
|
* --thread <name> Conversation thread name
|
|
8
8
|
* --provider <cli/xxx> Provider override
|
|
9
|
+
* --model <name> Model override (e.g. claude-sonnet-5)
|
|
9
10
|
* --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
|
|
10
11
|
* e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
11
12
|
* --verbose Debug output mode (default: raw agent response only)
|
|
@@ -27,6 +28,7 @@ const parse_common_flags_1 = require("./parse-common-flags");
|
|
|
27
28
|
const resolve_prompt_1 = require("./resolve-prompt");
|
|
28
29
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
29
30
|
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
31
|
+
const write_output_1 = require("./write-output");
|
|
30
32
|
/**
|
|
31
33
|
* Handle `crewx query <agentRef> <message>` command.
|
|
32
34
|
*
|
|
@@ -34,7 +36,7 @@ const inherited_trace_1 = require("../utils/inherited-trace");
|
|
|
34
36
|
* --verbose: debug info written to stderr, response to stdout.
|
|
35
37
|
*/
|
|
36
38
|
async function handleQuery(args) {
|
|
37
|
-
const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, vars, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
39
|
+
const { thread, provider, model, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
38
40
|
const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
|
|
39
41
|
// No @mention → default to @crewx agent (matches cli-bak behaviour)
|
|
40
42
|
const agentRef = parsedAgentRef || '@crewx';
|
|
@@ -55,6 +57,7 @@ async function handleQuery(args) {
|
|
|
55
57
|
console.error('Options:');
|
|
56
58
|
console.error(' --thread <name> Conversation thread name');
|
|
57
59
|
console.error(' --provider <cli/xxx> Provider override');
|
|
60
|
+
console.error(' --model <name> Model override (e.g. claude-sonnet-5)');
|
|
58
61
|
console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
|
|
59
62
|
console.error(' Propagated to events/hooks/tracing.');
|
|
60
63
|
console.error(' Invalid JSON aborts with exit code 2.');
|
|
@@ -62,9 +65,11 @@ async function handleQuery(args) {
|
|
|
62
65
|
console.error(' --verbose Debug output mode');
|
|
63
66
|
console.error(' --config/-c <path> Config file path');
|
|
64
67
|
console.error(' --output-format <fmt> Output format (json|text|stream-json)');
|
|
68
|
+
console.error(' --out/-o <path> Save result to file (stdout suppressed)');
|
|
65
69
|
console.error(' --effort <level> Model effort (high|medium|low)');
|
|
66
70
|
console.error(' -f/--prompt-file <path> Read prompt body from file');
|
|
67
71
|
console.error(' --var key=value Template variable (repeatable)');
|
|
72
|
+
console.error(' --overdrive Activate overdrive (boost) profile for this request');
|
|
68
73
|
process.exit(1);
|
|
69
74
|
}
|
|
70
75
|
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
@@ -79,10 +84,14 @@ async function handleQuery(args) {
|
|
|
79
84
|
process.stderr.write(`🔗 Thread: ${thread}\n`);
|
|
80
85
|
if (provider)
|
|
81
86
|
process.stderr.write(`🔌 Provider: ${provider}\n`);
|
|
87
|
+
if (model)
|
|
88
|
+
process.stderr.write(`🧠 Model: ${model}\n`);
|
|
82
89
|
if (outputFormat)
|
|
83
90
|
process.stderr.write(`📄 Output-format: ${outputFormat}\n`);
|
|
84
91
|
if (effort)
|
|
85
92
|
process.stderr.write(`⚡ Effort: ${effort}\n`);
|
|
93
|
+
if (overdrive)
|
|
94
|
+
process.stderr.write(`🚀 Overdrive: ON\n`);
|
|
86
95
|
process.stderr.write('─'.repeat(60) + '\n');
|
|
87
96
|
}
|
|
88
97
|
let parsedMetadata = {};
|
|
@@ -98,7 +107,9 @@ async function handleQuery(args) {
|
|
|
98
107
|
try {
|
|
99
108
|
const result = await crewx.query(agentRef, finalMessage, {
|
|
100
109
|
provider,
|
|
110
|
+
model,
|
|
101
111
|
effort: effort || undefined,
|
|
112
|
+
overdrive: overdrive || undefined,
|
|
102
113
|
threadId: thread,
|
|
103
114
|
metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
|
|
104
115
|
vars: Object.keys(vars).length > 0 ? vars : undefined,
|
|
@@ -107,6 +118,7 @@ async function handleQuery(args) {
|
|
|
107
118
|
if (!result.ok) {
|
|
108
119
|
const errMsg = result.error?.message ?? 'Query failed';
|
|
109
120
|
console.error(errMsg);
|
|
121
|
+
(0, write_output_1.appendError)(out, errMsg);
|
|
110
122
|
exitCode = 1;
|
|
111
123
|
}
|
|
112
124
|
else {
|
|
@@ -119,7 +131,7 @@ async function handleQuery(args) {
|
|
|
119
131
|
process.stderr.write('\n📄 Response:\n');
|
|
120
132
|
process.stderr.write('─'.repeat(40) + '\n');
|
|
121
133
|
}
|
|
122
|
-
|
|
134
|
+
(0, write_output_1.writeResult)(out, result.data);
|
|
123
135
|
if (verbose) {
|
|
124
136
|
process.stderr.write('\n✅ Query completed successfully\n');
|
|
125
137
|
}
|
|
@@ -128,6 +140,7 @@ async function handleQuery(args) {
|
|
|
128
140
|
catch (err) {
|
|
129
141
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
130
142
|
console.error(`Error: ${errMsg}`);
|
|
143
|
+
(0, write_output_1.appendError)(out, `Error: ${errMsg}`);
|
|
131
144
|
exitCode = 1;
|
|
132
145
|
}
|
|
133
146
|
finally {
|
|
@@ -17,13 +17,15 @@ exports.KNOWN_COMMANDS = new Set([
|
|
|
17
17
|
'doctor', 'init',
|
|
18
18
|
'db',
|
|
19
19
|
'help',
|
|
20
|
+
'shortcut',
|
|
21
|
+
'publish',
|
|
20
22
|
'slack', 'slack:files',
|
|
21
23
|
'hook', 'hook-dispatch',
|
|
22
24
|
]);
|
|
23
25
|
/** Built-in tool commands routed via handleBuiltin(). */
|
|
24
26
|
exports.BUILTIN_COMMAND_NAMES = new Set([
|
|
25
27
|
'memory', 'search', 'doc', 'wbs', 'cron', 'workflow', 'skill', 'dreaming',
|
|
26
|
-
'wi', 'chromex',
|
|
28
|
+
'wi', 'chromex', 'notify',
|
|
27
29
|
]);
|
|
28
30
|
/** Commands not yet migrated from cli-bak — show a migration message. */
|
|
29
31
|
exports.NOT_YET_MIGRATED = new Set([
|
package/dist/commands/restart.js
CHANGED
|
@@ -43,18 +43,23 @@ function buildRetryPrefix(originalTaskId) {
|
|
|
43
43
|
* the string when present and non-empty, otherwise `undefined` so the
|
|
44
44
|
* agent's configured provider default is used.
|
|
45
45
|
*/
|
|
46
|
-
function
|
|
46
|
+
function parseTaskMetadata(metadata) {
|
|
47
47
|
if (!metadata)
|
|
48
|
-
return
|
|
48
|
+
return {};
|
|
49
49
|
try {
|
|
50
50
|
const parsed = JSON.parse(metadata);
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
52
|
+
? parsed
|
|
53
|
+
: {};
|
|
53
54
|
}
|
|
54
55
|
catch {
|
|
55
|
-
return
|
|
56
|
+
return {};
|
|
56
57
|
}
|
|
57
58
|
}
|
|
59
|
+
function extractProvider(metadata) {
|
|
60
|
+
const provider = metadata.provider;
|
|
61
|
+
return typeof provider === 'string' && provider.length > 0 ? provider : undefined;
|
|
62
|
+
}
|
|
58
63
|
async function handleRestart(args) {
|
|
59
64
|
const verbose = args.includes('--verbose');
|
|
60
65
|
const taskId = args.find((a) => !a.startsWith('--'));
|
|
@@ -96,7 +101,10 @@ async function handleRestart(args) {
|
|
|
96
101
|
// provider: recovered from metadata.provider (SDK-persisted). Falls back to
|
|
97
102
|
// the agent's configured provider when absent. This preserves a
|
|
98
103
|
// `crewx x --provider ...` choice across restart.
|
|
99
|
-
const
|
|
104
|
+
const originalMetadata = parseTaskMetadata(original.metadata);
|
|
105
|
+
const provider = extractProvider(originalMetadata);
|
|
106
|
+
const originalWasOverdrive = originalMetadata.overdrive === true;
|
|
107
|
+
const originalOverdriveMode = originalMetadata.overdriveState === 'latch' ? 'latch' : 'count';
|
|
100
108
|
(0, sdk_1.setAuditVerbose)(verbose);
|
|
101
109
|
if (verbose) {
|
|
102
110
|
process.stderr.write(`🔁 Restart: ${taskId} → ${newTaskId}\n`);
|
|
@@ -111,10 +119,16 @@ async function handleRestart(args) {
|
|
|
111
119
|
threadId: original.thread_id ?? undefined,
|
|
112
120
|
model,
|
|
113
121
|
provider,
|
|
122
|
+
...(originalWasOverdrive ? { overdrive: { mode: originalOverdriveMode } } : {}),
|
|
114
123
|
metadata: {
|
|
115
124
|
restartedFromTaskId: taskId,
|
|
116
125
|
// Back-compat / search convenience: mirror the Web UI metadata key.
|
|
117
126
|
retriedFromTaskId: taskId,
|
|
127
|
+
...(originalWasOverdrive ? {
|
|
128
|
+
overdrive: true,
|
|
129
|
+
overdriveState: originalOverdriveMode,
|
|
130
|
+
overdriveMode: mode,
|
|
131
|
+
} : {}),
|
|
118
132
|
},
|
|
119
133
|
trace: (0, inherited_trace_1.readInheritedTrace)(),
|
|
120
134
|
};
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
* Retrieves the result of a completed task by its ID.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* crewx result <task-id>
|
|
7
|
-
* crewx result <task-id> --json
|
|
8
|
-
* crewx result
|
|
6
|
+
* crewx result <task-id> Print raw result
|
|
7
|
+
* crewx result <task-id> --json Print full task record as JSON
|
|
8
|
+
* crewx result <task-id> --wait=N Poll (1s interval) up to N seconds for
|
|
9
|
+
* the task to leave 'running'. Exit 124 on
|
|
10
|
+
* timeout. --wait=0 behaves like no --wait
|
|
11
|
+
* (single immediate check).
|
|
12
|
+
* crewx result List recent tasks (latest 10)
|
|
9
13
|
*/
|
|
10
14
|
export declare function handleResult(args: string[]): Promise<void>;
|
package/dist/commands/result.js
CHANGED
|
@@ -4,13 +4,19 @@
|
|
|
4
4
|
* Retrieves the result of a completed task by its ID.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* crewx result <task-id>
|
|
8
|
-
* crewx result <task-id> --json
|
|
9
|
-
* crewx result
|
|
7
|
+
* crewx result <task-id> Print raw result
|
|
8
|
+
* crewx result <task-id> --json Print full task record as JSON
|
|
9
|
+
* crewx result <task-id> --wait=N Poll (1s interval) up to N seconds for
|
|
10
|
+
* the task to leave 'running'. Exit 124 on
|
|
11
|
+
* timeout. --wait=0 behaves like no --wait
|
|
12
|
+
* (single immediate check).
|
|
13
|
+
* crewx result List recent tasks (latest 10)
|
|
10
14
|
*/
|
|
11
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
16
|
exports.handleResult = handleResult;
|
|
17
|
+
const sdk_1 = require("@crewx/sdk");
|
|
13
18
|
const repository_1 = require("@crewx/sdk/repository");
|
|
19
|
+
const POLL_INTERVAL_MS = 1000;
|
|
14
20
|
function statusIcon(status) {
|
|
15
21
|
switch (status) {
|
|
16
22
|
case 'running': return '⏳';
|
|
@@ -19,8 +25,20 @@ function statusIcon(status) {
|
|
|
19
25
|
default: return '❓';
|
|
20
26
|
}
|
|
21
27
|
}
|
|
28
|
+
function sleep(ms) {
|
|
29
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
30
|
+
}
|
|
31
|
+
/** Parses `--wait=N` (seconds). Returns undefined when the flag is absent. */
|
|
32
|
+
function parseWaitSeconds(args) {
|
|
33
|
+
const arg = args.find(a => a.startsWith('--wait='));
|
|
34
|
+
if (arg === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
const n = Number(arg.slice('--wait='.length));
|
|
37
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
38
|
+
}
|
|
22
39
|
async function handleResult(args) {
|
|
23
40
|
const jsonMode = args.includes('--json');
|
|
41
|
+
const waitSeconds = parseWaitSeconds(args);
|
|
24
42
|
const taskId = args.find(a => !a.startsWith('--'));
|
|
25
43
|
const repo = new repository_1.TaskRepository();
|
|
26
44
|
if (!taskId) {
|
|
@@ -36,21 +54,38 @@ async function handleResult(args) {
|
|
|
36
54
|
const icon = statusIcon(task.status);
|
|
37
55
|
console.log(`${idx + 1}. ${icon} ${task.id}`);
|
|
38
56
|
console.log(` Agent: ${task.agent_id ?? '—'} Mode: ${task.mode ?? '—'}`);
|
|
39
|
-
console.log(` Started: ${new Date(task.started_at)
|
|
57
|
+
console.log(` Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
|
|
40
58
|
if (task.completed_at) {
|
|
41
|
-
console.log(` Completed: ${new Date(task.completed_at)
|
|
59
|
+
console.log(` Completed: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.completed_at))}`);
|
|
42
60
|
}
|
|
43
61
|
console.log('');
|
|
44
62
|
});
|
|
45
63
|
console.log('Tip: Run `crewx result <task-id>` to see full output.');
|
|
46
64
|
return;
|
|
47
65
|
}
|
|
48
|
-
|
|
66
|
+
let task = repo.getTask(taskId);
|
|
49
67
|
if (!task) {
|
|
50
68
|
console.error(`Error: Task not found: ${taskId}`);
|
|
51
69
|
process.exit(1);
|
|
52
70
|
return;
|
|
53
71
|
}
|
|
72
|
+
if (waitSeconds !== undefined && waitSeconds > 0 && task.status === 'running') {
|
|
73
|
+
const deadline = Date.now() + waitSeconds * 1000;
|
|
74
|
+
while (task && task.status === 'running') {
|
|
75
|
+
if (Date.now() >= deadline) {
|
|
76
|
+
console.error(`Task ${taskId} did not complete within --wait=${waitSeconds}s (status: running).`);
|
|
77
|
+
process.exit(124);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await sleep(Math.min(POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())));
|
|
81
|
+
task = repo.getTask(taskId);
|
|
82
|
+
if (!task) {
|
|
83
|
+
console.error(`Error: Task not found: ${taskId}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
54
89
|
if (jsonMode) {
|
|
55
90
|
console.log(JSON.stringify(task, null, 2));
|
|
56
91
|
return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleShortcut(args: string[]): Promise<void>;
|