@crewx/cli 0.9.0-rc.82 → 0.9.0-rc.83
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/emit-trailer.d.ts +25 -0
- package/dist/commands/emit-trailer.js +33 -0
- package/dist/commands/execute.d.ts +2 -1
- package/dist/commands/execute.js +61 -10
- package/dist/commands/publish.js +28 -8
- package/dist/commands/query.d.ts +2 -1
- package/dist/commands/query.js +61 -10
- package/dist/main.js +9 -6
- package/dist/utils/sdk-compat.d.ts +3 -0
- package/dist/utils/sdk-compat.js +50 -2
- package/package.json +12 -12
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TraceContext } from '@crewx/sdk';
|
|
2
|
+
/** Mutable per-process guard shared by a handler and main()'s error boundary. */
|
|
3
|
+
export interface DelegationEmitState {
|
|
4
|
+
emitted: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** The result fields needed to produce a delegation control line. */
|
|
7
|
+
export interface DelegationEmitOptions {
|
|
8
|
+
command?: string;
|
|
9
|
+
trace?: TraceContext;
|
|
10
|
+
taskId?: string;
|
|
11
|
+
agentId?: string;
|
|
12
|
+
isError: boolean;
|
|
13
|
+
state?: DelegationEmitState;
|
|
14
|
+
}
|
|
15
|
+
export declare function createDelegationEmitState(): DelegationEmitState;
|
|
16
|
+
/**
|
|
17
|
+
* Return true only for an inherited child invocation of q/query/x/execute.
|
|
18
|
+
* Root CLI calls and unrelated built-in commands must remain byte-compatible.
|
|
19
|
+
*/
|
|
20
|
+
export declare function shouldEmitDelegationResult(command: string | undefined, trace?: TraceContext | undefined): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Write one machine-readable result line to stdout when this is a delegated call.
|
|
23
|
+
* The shared SDK formatter owns the wire syntax and validation rules.
|
|
24
|
+
*/
|
|
25
|
+
export declare function emitDelegationResult(options: DelegationEmitOptions): boolean;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDelegationEmitState = createDelegationEmitState;
|
|
4
|
+
exports.shouldEmitDelegationResult = shouldEmitDelegationResult;
|
|
5
|
+
exports.emitDelegationResult = emitDelegationResult;
|
|
6
|
+
const sdk_1 = require("@crewx/sdk");
|
|
7
|
+
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
8
|
+
const DELEGATION_COMMANDS = new Set(['q', 'query', 'x', 'execute']);
|
|
9
|
+
function createDelegationEmitState() {
|
|
10
|
+
return { emitted: false };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Return true only for an inherited child invocation of q/query/x/execute.
|
|
14
|
+
* Root CLI calls and unrelated built-in commands must remain byte-compatible.
|
|
15
|
+
*/
|
|
16
|
+
function shouldEmitDelegationResult(command, trace = (0, inherited_trace_1.readInheritedTrace)()) {
|
|
17
|
+
return DELEGATION_COMMANDS.has(command ?? '') && Boolean(trace?.parentTaskId);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Write one machine-readable result line to stdout when this is a delegated call.
|
|
21
|
+
* The shared SDK formatter owns the wire syntax and validation rules.
|
|
22
|
+
*/
|
|
23
|
+
function emitDelegationResult(options) {
|
|
24
|
+
const { command, trace, state, taskId, agentId, isError } = options;
|
|
25
|
+
if (state?.emitted || !shouldEmitDelegationResult(command, trace))
|
|
26
|
+
return false;
|
|
27
|
+
const line = (0, sdk_1.formatDelegationResult)({ taskId, agentId, isError });
|
|
28
|
+
// Mark before writing so an EPIPE/error boundary cannot accidentally retry.
|
|
29
|
+
if (state)
|
|
30
|
+
state.emitted = true;
|
|
31
|
+
process.stdout.write(`${line}\n`);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
* e.g. cat task.md | crewx x "@agent label"
|
|
23
23
|
* Stdin is ignored when running in an interactive TTY.
|
|
24
24
|
*/
|
|
25
|
+
import { type DelegationEmitState } from './emit-trailer';
|
|
25
26
|
/**
|
|
26
27
|
* Handle `crewx execute <agentRef> <message>` command.
|
|
27
28
|
*
|
|
28
29
|
* Default output: raw agent response only (stdout).
|
|
29
30
|
* --verbose: debug info written to stderr, response to stdout.
|
|
30
31
|
*/
|
|
31
|
-
export declare function handleExecute(args: string[]): Promise<void>;
|
|
32
|
+
export declare function handleExecute(args: string[], command?: string, emitState?: DelegationEmitState): Promise<void>;
|
package/dist/commands/execute.js
CHANGED
|
@@ -36,6 +36,7 @@ const resolve_prompt_1 = require("./resolve-prompt");
|
|
|
36
36
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
37
37
|
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
38
38
|
const write_output_1 = require("./write-output");
|
|
39
|
+
const emit_trailer_1 = require("./emit-trailer");
|
|
39
40
|
/**
|
|
40
41
|
* Split `--detach` out of argv, respecting the `--` literal-args sentinel
|
|
41
42
|
* (a `--detach` appearing after `--` is message text, not the flag).
|
|
@@ -97,7 +98,7 @@ function runDetached(filteredArgs) {
|
|
|
97
98
|
* Default output: raw agent response only (stdout).
|
|
98
99
|
* --verbose: debug info written to stderr, response to stdout.
|
|
99
100
|
*/
|
|
100
|
-
async function handleExecute(args) {
|
|
101
|
+
async function handleExecute(args, command = 'execute', emitState = (0, emit_trailer_1.createDelegationEmitState)()) {
|
|
101
102
|
const { detach, rest: detachFilteredArgs } = extractDetachFlag(args);
|
|
102
103
|
if (detach) {
|
|
103
104
|
// Recursive-spawn guard: a CREWX_TRACE_ID already present means this
|
|
@@ -109,6 +110,7 @@ async function handleExecute(args) {
|
|
|
109
110
|
}
|
|
110
111
|
else if (process.platform === 'win32') {
|
|
111
112
|
console.error('Error: --detach is not supported on win32.');
|
|
113
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, isError: true, state: emitState });
|
|
112
114
|
process.exit(1);
|
|
113
115
|
return;
|
|
114
116
|
}
|
|
@@ -117,12 +119,29 @@ async function handleExecute(args) {
|
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
let parsedFlags;
|
|
123
|
+
try {
|
|
124
|
+
parsedFlags = (0, parse_common_flags_1.parseCommonFlags)(detachFilteredArgs);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, isError: true, state: emitState });
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
const { thread, provider, model, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = parsedFlags;
|
|
131
|
+
const inheritedTrace = (0, inherited_trace_1.readInheritedTrace)();
|
|
132
|
+
let parsedAgentRef;
|
|
133
|
+
let message;
|
|
134
|
+
let finalMessage;
|
|
135
|
+
try {
|
|
136
|
+
({ agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest));
|
|
137
|
+
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
138
|
+
finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
123
144
|
const agentRef = parsedAgentRef || '@crewx';
|
|
124
|
-
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
125
|
-
const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
126
145
|
if (!finalMessage) {
|
|
127
146
|
console.error('Usage: crewx execute [@agent] <task> [options]');
|
|
128
147
|
console.error(' crewx x [@agent] <task> [options]');
|
|
@@ -151,12 +170,21 @@ async function handleExecute(args) {
|
|
|
151
170
|
console.error(' -f/--prompt-file <path> Read task body from file');
|
|
152
171
|
console.error(' --var key=value Template variable (repeatable)');
|
|
153
172
|
console.error(' --overdrive Activate overdrive (boost) profile for this request');
|
|
173
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
154
174
|
process.exit(1);
|
|
175
|
+
return;
|
|
155
176
|
}
|
|
156
177
|
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
157
178
|
// Only show exec audit span JSON in verbose mode
|
|
158
179
|
(0, sdk_1.setAuditVerbose)(verbose);
|
|
159
|
-
|
|
180
|
+
let crewx;
|
|
181
|
+
try {
|
|
182
|
+
crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
186
|
+
throw err;
|
|
187
|
+
}
|
|
160
188
|
// file:// remote agent delegation is handled transparently inside Crewx.query/execute.
|
|
161
189
|
if (verbose) {
|
|
162
190
|
process.stderr.write(`📋 Task: ${finalMessage}\n`);
|
|
@@ -182,9 +210,10 @@ async function handleExecute(args) {
|
|
|
182
210
|
catch (err) {
|
|
183
211
|
const msg = err instanceof Error ? err.message : String(err);
|
|
184
212
|
process.stderr.write(`Error: ${msg}\n`);
|
|
213
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
185
214
|
process.exit(2);
|
|
215
|
+
return;
|
|
186
216
|
}
|
|
187
|
-
const inheritedTrace = (0, inherited_trace_1.readInheritedTrace)();
|
|
188
217
|
// A trace with a rootTraceId but no parentTaskId means the id was pre-assigned
|
|
189
218
|
// to *this* task itself (the detach runner's parent injects only CREWX_TRACE_ID,
|
|
190
219
|
// never CREWX_PARENT_TASK_ID — see execute.ts's runDetached), not inherited from
|
|
@@ -194,8 +223,9 @@ async function handleExecute(args) {
|
|
|
194
223
|
? (inheritedTrace.rootTraceId || undefined)
|
|
195
224
|
: undefined;
|
|
196
225
|
let exitCode = 0;
|
|
226
|
+
let result;
|
|
197
227
|
try {
|
|
198
|
-
|
|
228
|
+
result = await crewx.execute(agentRef, finalMessage, {
|
|
199
229
|
provider,
|
|
200
230
|
model,
|
|
201
231
|
effort: effort || undefined,
|
|
@@ -235,8 +265,29 @@ async function handleExecute(args) {
|
|
|
235
265
|
exitCode = 1;
|
|
236
266
|
}
|
|
237
267
|
finally {
|
|
238
|
-
|
|
268
|
+
try {
|
|
269
|
+
await crewx.close();
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
273
|
+
command,
|
|
274
|
+
trace: inheritedTrace,
|
|
275
|
+
taskId: result?.meta.taskId,
|
|
276
|
+
agentId: result?.meta.agentId,
|
|
277
|
+
isError: true,
|
|
278
|
+
state: emitState,
|
|
279
|
+
});
|
|
280
|
+
throw err;
|
|
281
|
+
}
|
|
239
282
|
}
|
|
283
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
284
|
+
command,
|
|
285
|
+
trace: inheritedTrace,
|
|
286
|
+
taskId: result?.meta.taskId,
|
|
287
|
+
agentId: result?.meta.agentId,
|
|
288
|
+
isError: exitCode !== 0 || result?.ok === false,
|
|
289
|
+
state: emitState,
|
|
290
|
+
});
|
|
240
291
|
if (exitCode !== 0)
|
|
241
292
|
process.exit(exitCode);
|
|
242
293
|
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -44,10 +44,11 @@ exports.handlePublish = handlePublish;
|
|
|
44
44
|
* tar.gz packing lives in @crewx/sdk/publish (planPublish / packTemplate).
|
|
45
45
|
* Submit+upload (WI-SHR-20260806-013) lives in the same package
|
|
46
46
|
* (uploadToMarketplace) for the same reason — see that module's header.
|
|
47
|
-
* This command only parses argv, forwards options,
|
|
48
|
-
*
|
|
47
|
+
* This command only parses argv, forwards options, asks the SDK SessionManager
|
|
48
|
+
* for a valid account bearer when upload is requested, and renders the result.
|
|
49
49
|
*/
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
|
+
const account_1 = require("@crewx/sdk/account");
|
|
51
52
|
const publish_1 = require("@crewx/sdk/publish");
|
|
52
53
|
const parse_common_flags_1 = require("./parse-common-flags");
|
|
53
54
|
function parsePublishFlags(args) {
|
|
@@ -138,10 +139,26 @@ Notes:
|
|
|
138
139
|
/** CREWX_MARKETPLACE_URL — same env var name as the server's MARKETPLACE_DISABLED check, never a second name. */
|
|
139
140
|
function requireMarketplaceUrl() {
|
|
140
141
|
const url = process.env['CREWX_MARKETPLACE_URL'];
|
|
141
|
-
if (!url) {
|
|
142
|
+
if (!url?.trim()) {
|
|
142
143
|
throw new Error('publish: [E_ENV_MISSING] CREWX_MARKETPLACE_URL is not set — this environment variable is required for upload');
|
|
143
144
|
}
|
|
144
|
-
return url;
|
|
145
|
+
return url.trim();
|
|
146
|
+
}
|
|
147
|
+
function isMarketplaceUnauthorized(err) {
|
|
148
|
+
return err instanceof Error
|
|
149
|
+
&& err.message.includes('publish: [E_AUTH_EXPIRED]')
|
|
150
|
+
&& /HTTP 401\b/.test(err.message);
|
|
151
|
+
}
|
|
152
|
+
async function uploadWithSessionRefresh(sessionManager, options, accessToken) {
|
|
153
|
+
try {
|
|
154
|
+
return await (0, publish_1.uploadToMarketplace)({ ...options, accessToken });
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
if (!isMarketplaceUnauthorized(err))
|
|
158
|
+
throw err;
|
|
159
|
+
const refreshedSession = await sessionManager.refresh();
|
|
160
|
+
return (0, publish_1.uploadToMarketplace)({ ...options, accessToken: refreshedSession.access_token });
|
|
161
|
+
}
|
|
145
162
|
}
|
|
146
163
|
async function handlePublish(args) {
|
|
147
164
|
const flags = parsePublishFlags(args);
|
|
@@ -198,10 +215,12 @@ async function handlePublish(args) {
|
|
|
198
215
|
// workspace — WI-SHR-20260806-013 AC-U5.
|
|
199
216
|
let marketplaceUrl = '';
|
|
200
217
|
let accessToken = '';
|
|
218
|
+
let sessionManager;
|
|
201
219
|
if (flags.upload) {
|
|
202
220
|
try {
|
|
203
221
|
marketplaceUrl = requireMarketplaceUrl();
|
|
204
|
-
|
|
222
|
+
sessionManager = new account_1.SessionManager({ authClient: new account_1.AuthClient() });
|
|
223
|
+
accessToken = await sessionManager.getAccessToken();
|
|
205
224
|
}
|
|
206
225
|
catch (err) {
|
|
207
226
|
if (err instanceof Error && !err.message.startsWith('publish: [')) {
|
|
@@ -224,12 +243,13 @@ async function handlePublish(args) {
|
|
|
224
243
|
if (flags.upload) {
|
|
225
244
|
process.stderr.write(`[publish] uploading ${packed.manifest.name}@${packed.manifest.version} to ${marketplaceUrl}...\n`);
|
|
226
245
|
try {
|
|
227
|
-
|
|
246
|
+
if (!sessionManager)
|
|
247
|
+
throw new Error('publish: [E_AUTH_EXPIRED] Account session is unavailable');
|
|
248
|
+
uploadResult = await uploadWithSessionRefresh(sessionManager, {
|
|
228
249
|
tgzPath: packed.tgzPath,
|
|
229
250
|
manifest: packed.manifest,
|
|
230
251
|
baseUrl: marketplaceUrl,
|
|
231
|
-
|
|
232
|
-
});
|
|
252
|
+
}, accessToken);
|
|
233
253
|
}
|
|
234
254
|
catch (err) {
|
|
235
255
|
failWithError(err, flags.json);
|
package/dist/commands/query.d.ts
CHANGED
|
@@ -19,10 +19,11 @@
|
|
|
19
19
|
* e.g. cat brief.md | crewx q "@agent label"
|
|
20
20
|
* Stdin is ignored when running in an interactive TTY.
|
|
21
21
|
*/
|
|
22
|
+
import { type DelegationEmitState } from './emit-trailer';
|
|
22
23
|
/**
|
|
23
24
|
* Handle `crewx query <agentRef> <message>` command.
|
|
24
25
|
*
|
|
25
26
|
* Default output: raw agent response only (stdout).
|
|
26
27
|
* --verbose: debug info written to stderr, response to stdout.
|
|
27
28
|
*/
|
|
28
|
-
export declare function handleQuery(args: string[]): Promise<void>;
|
|
29
|
+
export declare function handleQuery(args: string[], command?: string, emitState?: DelegationEmitState): Promise<void>;
|
package/dist/commands/query.js
CHANGED
|
@@ -29,19 +29,37 @@ const resolve_prompt_1 = require("./resolve-prompt");
|
|
|
29
29
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
30
30
|
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
31
31
|
const write_output_1 = require("./write-output");
|
|
32
|
+
const emit_trailer_1 = require("./emit-trailer");
|
|
32
33
|
/**
|
|
33
34
|
* Handle `crewx query <agentRef> <message>` command.
|
|
34
35
|
*
|
|
35
36
|
* Default output: raw agent response only (stdout).
|
|
36
37
|
* --verbose: debug info written to stderr, response to stdout.
|
|
37
38
|
*/
|
|
38
|
-
async function handleQuery(args) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
async function handleQuery(args, command = 'query', emitState = (0, emit_trailer_1.createDelegationEmitState)()) {
|
|
40
|
+
let parsedFlags;
|
|
41
|
+
try {
|
|
42
|
+
parsedFlags = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, isError: true, state: emitState });
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
const { thread, provider, model, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = parsedFlags;
|
|
49
|
+
const inheritedTrace = (0, inherited_trace_1.readInheritedTrace)();
|
|
50
|
+
let parsedAgentRef;
|
|
51
|
+
let message;
|
|
52
|
+
let finalMessage;
|
|
53
|
+
try {
|
|
54
|
+
({ agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest));
|
|
55
|
+
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
56
|
+
finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
42
62
|
const agentRef = parsedAgentRef || '@crewx';
|
|
43
|
-
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
44
|
-
const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
45
63
|
if (!finalMessage) {
|
|
46
64
|
console.error('Usage: crewx query [@agent] <message> [options]');
|
|
47
65
|
console.error(' crewx q [@agent] <message> [options]');
|
|
@@ -70,12 +88,21 @@ async function handleQuery(args) {
|
|
|
70
88
|
console.error(' -f/--prompt-file <path> Read prompt body from file');
|
|
71
89
|
console.error(' --var key=value Template variable (repeatable)');
|
|
72
90
|
console.error(' --overdrive Activate overdrive (boost) profile for this request');
|
|
91
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
73
92
|
process.exit(1);
|
|
93
|
+
return;
|
|
74
94
|
}
|
|
75
95
|
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
76
96
|
// Only show exec audit span JSON in verbose mode
|
|
77
97
|
(0, sdk_1.setAuditVerbose)(verbose);
|
|
78
|
-
|
|
98
|
+
let crewx;
|
|
99
|
+
try {
|
|
100
|
+
crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
79
106
|
// file:// remote agent delegation is handled transparently inside Crewx.query/execute.
|
|
80
107
|
if (verbose) {
|
|
81
108
|
process.stderr.write(`📋 Task: ${finalMessage}\n`);
|
|
@@ -101,11 +128,14 @@ async function handleQuery(args) {
|
|
|
101
128
|
catch (err) {
|
|
102
129
|
const msg = err instanceof Error ? err.message : String(err);
|
|
103
130
|
process.stderr.write(`Error: ${msg}\n`);
|
|
131
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
104
132
|
process.exit(2);
|
|
133
|
+
return;
|
|
105
134
|
}
|
|
106
135
|
let exitCode = 0;
|
|
136
|
+
let result;
|
|
107
137
|
try {
|
|
108
|
-
|
|
138
|
+
result = await crewx.query(agentRef, finalMessage, {
|
|
109
139
|
provider,
|
|
110
140
|
model,
|
|
111
141
|
effort: effort || undefined,
|
|
@@ -113,7 +143,7 @@ async function handleQuery(args) {
|
|
|
113
143
|
threadId: thread,
|
|
114
144
|
metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
|
|
115
145
|
vars: Object.keys(vars).length > 0 ? vars : undefined,
|
|
116
|
-
trace:
|
|
146
|
+
trace: inheritedTrace,
|
|
117
147
|
});
|
|
118
148
|
if (!result.ok) {
|
|
119
149
|
const errMsg = result.error?.message ?? 'Query failed';
|
|
@@ -144,8 +174,29 @@ async function handleQuery(args) {
|
|
|
144
174
|
exitCode = 1;
|
|
145
175
|
}
|
|
146
176
|
finally {
|
|
147
|
-
|
|
177
|
+
try {
|
|
178
|
+
await crewx.close();
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
182
|
+
command,
|
|
183
|
+
trace: inheritedTrace,
|
|
184
|
+
taskId: result?.meta.taskId,
|
|
185
|
+
agentId: result?.meta.agentId,
|
|
186
|
+
isError: true,
|
|
187
|
+
state: emitState,
|
|
188
|
+
});
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
148
191
|
}
|
|
192
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
193
|
+
command,
|
|
194
|
+
trace: inheritedTrace,
|
|
195
|
+
taskId: result?.meta.taskId,
|
|
196
|
+
agentId: result?.meta.agentId,
|
|
197
|
+
isError: exitCode !== 0 || result?.ok === false,
|
|
198
|
+
state: emitState,
|
|
199
|
+
});
|
|
149
200
|
if (exitCode !== 0)
|
|
150
201
|
process.exit(exitCode);
|
|
151
202
|
}
|
package/dist/main.js
CHANGED
|
@@ -84,6 +84,7 @@ const db_1 = require("./commands/db");
|
|
|
84
84
|
const parse_common_flags_1 = require("./commands/parse-common-flags");
|
|
85
85
|
const registry_1 = require("./commands/registry");
|
|
86
86
|
const version_1 = require("./utils/version");
|
|
87
|
+
const emit_trailer_1 = require("./commands/emit-trailer");
|
|
87
88
|
/**
|
|
88
89
|
* Dev-only SSOT assertion: bin/cli-commands.js must be the exact union of
|
|
89
90
|
* KNOWN_COMMANDS ∪ BUILTIN_COMMAND_NAMES ∪ NOT_YET_MIGRATED from registry.ts.
|
|
@@ -108,7 +109,7 @@ async function assertSsotParity() {
|
|
|
108
109
|
(extra.length ? ` CLI_SUBCOMMANDS has, registry missing: ${extra.join(', ')}` : ''));
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
|
-
async function main() {
|
|
112
|
+
async function main(emitState) {
|
|
112
113
|
if (process.env['NODE_ENV'] === 'development') {
|
|
113
114
|
await assertSsotParity();
|
|
114
115
|
}
|
|
@@ -128,11 +129,11 @@ async function main() {
|
|
|
128
129
|
// P0-2: q/x aliases
|
|
129
130
|
case 'q':
|
|
130
131
|
case 'query':
|
|
131
|
-
await (0, query_1.handleQuery)(args.slice(1));
|
|
132
|
+
await (0, query_1.handleQuery)(args.slice(1), command, emitState);
|
|
132
133
|
return;
|
|
133
134
|
case 'x':
|
|
134
135
|
case 'execute':
|
|
135
|
-
await (0, execute_1.handleExecute)(args.slice(1));
|
|
136
|
+
await (0, execute_1.handleExecute)(args.slice(1), command, emitState);
|
|
136
137
|
return;
|
|
137
138
|
case 'agent':
|
|
138
139
|
await (0, agent_1.handleAgent)(args.slice(1));
|
|
@@ -194,7 +195,7 @@ async function main() {
|
|
|
194
195
|
case 'shortcut':
|
|
195
196
|
await (0, shortcut_1.handleShortcut)(args.slice(1));
|
|
196
197
|
return;
|
|
197
|
-
//
|
|
198
|
+
// crewx publish [dir] [--dry-run] [--version <semver>] [--json] [--upload]
|
|
198
199
|
case 'publish':
|
|
199
200
|
await (0, publish_1.handlePublish)(args.slice(1));
|
|
200
201
|
return;
|
|
@@ -332,7 +333,7 @@ Publish:
|
|
|
332
333
|
--dry-run Scan + build manifest only; do not write a .tgz
|
|
333
334
|
--version <ver> Override manifest version (semver)
|
|
334
335
|
--json Print machine-readable JSON to stdout
|
|
335
|
-
|
|
336
|
+
--upload Submit + upload using the SDK account session
|
|
336
337
|
|
|
337
338
|
Built-in Tools:
|
|
338
339
|
memory <args> Memory tool
|
|
@@ -354,7 +355,9 @@ Global Options:
|
|
|
354
355
|
--version, -v Show version
|
|
355
356
|
`.trim());
|
|
356
357
|
}
|
|
357
|
-
|
|
358
|
+
const emitState = (0, emit_trailer_1.createDelegationEmitState)();
|
|
359
|
+
main(emitState).catch((err) => {
|
|
358
360
|
console.error(err instanceof Error ? err.message : String(err));
|
|
361
|
+
(0, emit_trailer_1.emitDelegationResult)({ command: process.argv[2], isError: true, state: emitState });
|
|
359
362
|
process.exit(err instanceof parse_common_flags_1.UnknownOptionError ? 2 : 1);
|
|
360
363
|
});
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import type { CrewxExecutableResolution } from '@crewx/sdk';
|
|
1
2
|
type PricingInitializer = () => Promise<unknown> | unknown;
|
|
2
3
|
export interface SdkLike {
|
|
3
4
|
resolveCrewxCli?: () => string;
|
|
5
|
+
resolveCrewxCliArgv?: () => CrewxExecutableResolution;
|
|
4
6
|
resolveCrewxWorkspace?: () => string;
|
|
5
7
|
initPricingRemote?: PricingInitializer;
|
|
6
8
|
}
|
|
7
9
|
export interface SdkCompat {
|
|
8
10
|
resolveCrewxCli(): string;
|
|
11
|
+
resolveCrewxCliArgv(): CrewxExecutableResolution;
|
|
9
12
|
resolveCrewxWorkspace(): string;
|
|
10
13
|
initPricingRemote(): void;
|
|
11
14
|
}
|
package/dist/utils/sdk-compat.js
CHANGED
|
@@ -36,6 +36,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.sdkCompat = void 0;
|
|
37
37
|
exports.createSdkCompat = createSdkCompat;
|
|
38
38
|
const sdk = __importStar(require("@crewx/sdk"));
|
|
39
|
+
function formatLegacyArgv(argv) {
|
|
40
|
+
const formatter = sdk.formatCrewxExecutableArgv;
|
|
41
|
+
if (typeof formatter === 'function')
|
|
42
|
+
return formatter(argv);
|
|
43
|
+
// Older SDKs may expose the argv resolver before exposing its formatter.
|
|
44
|
+
// Keep this compatibility-only fallback one-way and quote every token.
|
|
45
|
+
if (process.platform === 'win32') {
|
|
46
|
+
return argv
|
|
47
|
+
.map((value) => {
|
|
48
|
+
const escaped = value
|
|
49
|
+
.replace(/(\\*)"/g, '$1$1\\"')
|
|
50
|
+
.replace(/(\\+)$/g, '$1$1');
|
|
51
|
+
return `"${escaped}"`;
|
|
52
|
+
})
|
|
53
|
+
.join(' ');
|
|
54
|
+
}
|
|
55
|
+
return argv.map((value) => `'${value.replace(/'/g, `'\\''`)}'`).join(' ');
|
|
56
|
+
}
|
|
57
|
+
const FALLBACK_CREWX_CLI_DISPLAY = 'crewx';
|
|
58
|
+
function missingCliResolver() {
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
reason: 'The installed SDK does not expose the argv-based CrewX CLI resolver.',
|
|
62
|
+
attempts: [
|
|
63
|
+
{ stage: 'env', reason: 'argv resolver capability is unavailable' },
|
|
64
|
+
{ stage: 'self', reason: 'argv resolver capability is unavailable' },
|
|
65
|
+
{ stage: 'workspace', reason: 'argv resolver capability is unavailable' },
|
|
66
|
+
{ stage: 'module', reason: 'argv resolver capability is unavailable' },
|
|
67
|
+
{ stage: 'path', reason: 'argv resolver capability is unavailable' },
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
39
71
|
/**
|
|
40
72
|
* Create the CLI bootstrap capability accessor for the installed SDK.
|
|
41
73
|
*
|
|
@@ -46,10 +78,26 @@ const sdk = __importStar(require("@crewx/sdk"));
|
|
|
46
78
|
function createSdkCompat(sdkLike = sdk) {
|
|
47
79
|
return {
|
|
48
80
|
resolveCrewxCli: () => {
|
|
81
|
+
const configured = process.env.CREWX_CLI;
|
|
82
|
+
if (configured?.trim())
|
|
83
|
+
return configured;
|
|
84
|
+
if (typeof sdkLike.resolveCrewxCliArgv === 'function') {
|
|
85
|
+
const resolution = sdkLike.resolveCrewxCliArgv();
|
|
86
|
+
if (resolution.ok)
|
|
87
|
+
return formatLegacyArgv(resolution.argv);
|
|
88
|
+
}
|
|
49
89
|
if (typeof sdkLike.resolveCrewxCli === 'function') {
|
|
50
|
-
|
|
90
|
+
const value = sdkLike.resolveCrewxCli();
|
|
91
|
+
if (value.trim())
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
return FALLBACK_CREWX_CLI_DISPLAY;
|
|
95
|
+
},
|
|
96
|
+
resolveCrewxCliArgv: () => {
|
|
97
|
+
if (typeof sdkLike.resolveCrewxCliArgv === 'function') {
|
|
98
|
+
return sdkLike.resolveCrewxCliArgv();
|
|
51
99
|
}
|
|
52
|
-
return
|
|
100
|
+
return missingCliResolver();
|
|
53
101
|
},
|
|
54
102
|
resolveCrewxWorkspace: () => {
|
|
55
103
|
if (typeof sdkLike.resolveCrewxWorkspace === 'function') {
|
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.83",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.19.0"
|
|
@@ -25,18 +25,18 @@
|
|
|
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/
|
|
31
|
-
"@crewx/
|
|
32
|
-
"@crewx/
|
|
33
|
-
"@crewx/cron": "0.1.10-rc.
|
|
28
|
+
"@crewx/sdk": "0.9.0-rc.83",
|
|
29
|
+
"@crewx/search": "0.1.10-rc.79",
|
|
30
|
+
"@crewx/doc": "0.1.9-rc.76",
|
|
31
|
+
"@crewx/wbs": "0.1.10-rc.109",
|
|
32
|
+
"@crewx/workflow": "0.3.22-rc.129",
|
|
33
|
+
"@crewx/cron": "0.1.10-rc.118",
|
|
34
|
+
"@crewx/chromex": "0.1.0-rc.116",
|
|
35
|
+
"@crewx/notify": "0.1.0-rc.54",
|
|
36
|
+
"@crewx/wi": "0.1.10-rc.103",
|
|
37
|
+
"@crewx/memory": "0.1.23-rc.100",
|
|
34
38
|
"@crewx/skill": "0.1.20",
|
|
35
|
-
"@crewx/
|
|
36
|
-
"@crewx/shared": "0.0.6",
|
|
37
|
-
"@crewx/wi": "0.1.10-rc.102",
|
|
38
|
-
"@crewx/notify": "0.1.0-rc.53",
|
|
39
|
-
"@crewx/chromex": "0.1.0-rc.115"
|
|
39
|
+
"@crewx/shared": "0.0.6"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/better-sqlite3": "*",
|