@crewx/cli 0.9.0-rc.19 → 0.9.0-rc.191
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 +20 -1
- package/dist/bootstrap/codex-writable-roots.js +1 -88
- package/dist/bootstrap/crewx-cli.js +1 -63
- package/dist/bootstrap/rate-limit-snapshot.d.ts +15 -0
- package/dist/bootstrap/rate-limit-snapshot.js +1 -0
- package/dist/builtin.d.ts +1 -1
- package/dist/builtin.js +5 -127
- package/dist/commands/agent.d.ts +1 -0
- package/dist/commands/agent.js +3 -246
- package/dist/commands/ai-account.d.ts +16 -0
- package/dist/commands/ai-account.js +38 -0
- package/dist/commands/cal.d.ts +15 -0
- package/dist/commands/cal.js +2 -0
- package/dist/commands/command-help.d.ts +28 -0
- package/dist/commands/command-help.js +87 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.js +59 -125
- package/dist/commands/detached.d.ts +121 -0
- package/dist/commands/detached.js +15 -0
- package/dist/commands/doctor.d.ts +77 -0
- package/dist/commands/doctor.js +4 -196
- package/dist/commands/emit-trailer.d.ts +25 -0
- package/dist/commands/emit-trailer.js +2 -0
- package/dist/commands/execute.d.ts +8 -4
- package/dist/commands/execute.js +15 -146
- package/dist/commands/history.d.ts +18 -0
- package/dist/commands/history.js +2 -0
- package/dist/commands/hook/command-marker.d.ts +2 -0
- package/dist/commands/hook/command-marker.js +1 -0
- package/dist/commands/hook/install.d.ts +0 -1
- package/dist/commands/hook/install.js +8 -175
- package/dist/commands/hook/paths.js +1 -94
- package/dist/commands/hook/status.js +1 -86
- package/dist/commands/hook/uninstall.js +1 -71
- package/dist/commands/hook-dispatch.js +2 -180
- package/dist/commands/init.d.ts +34 -0
- package/dist/commands/init.js +38 -371
- package/dist/commands/kill.d.ts +2 -8
- package/dist/commands/kill.js +1 -52
- package/dist/commands/log.js +3 -95
- package/dist/commands/parse-agent-message.js +1 -52
- package/dist/commands/parse-common-flags.d.ts +5 -1
- package/dist/commands/parse-common-flags.js +3 -181
- package/dist/commands/ps.d.ts +2 -2
- package/dist/commands/ps.js +2 -107
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.js +27 -0
- package/dist/commands/query.d.ts +7 -2
- package/dist/commands/query.js +16 -146
- package/dist/commands/registry.js +1 -31
- package/dist/commands/resolve-prompt.js +3 -54
- package/dist/commands/resolve-recipient.d.ts +14 -0
- package/dist/commands/resolve-recipient.js +3 -0
- package/dist/commands/restart.d.ts +3 -1
- package/dist/commands/restart.js +18 -162
- package/dist/commands/result.d.ts +8 -3
- package/dist/commands/result.js +1 -70
- package/dist/commands/shortcut.d.ts +1 -0
- package/dist/commands/shortcut.js +18 -0
- package/dist/commands/slack.js +16 -559
- package/dist/commands/stop.d.ts +8 -0
- package/dist/commands/stop.js +8 -0
- package/dist/commands/write-output.js +1 -24
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -5
- package/dist/logging.d.ts +1 -1
- package/dist/logging.js +10 -86
- package/dist/main.d.ts +3 -2
- package/dist/main.js +51 -253
- package/dist/register-builtin-tools.js +1 -9
- package/dist/slack/file-download.js +1 -134
- package/dist/slack/markdown.js +1 -33
- package/dist/utils/env-defaults.d.ts +2 -5
- package/dist/utils/env-defaults.js +1 -10
- package/dist/utils/inherited-trace.d.ts +24 -0
- package/dist/utils/inherited-trace.js +1 -25
- package/dist/utils/product-package-root.d.ts +6 -0
- package/dist/utils/product-package-root.js +1 -0
- package/dist/utils/sdk-compat.d.ts +24 -0
- package/dist/utils/sdk-compat.js +1 -0
- package/dist/utils/version.js +1 -28
- package/package.json +16 -12
package/dist/commands/query.js
CHANGED
|
@@ -1,146 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* Stdin support:
|
|
18
|
-
* Pipe or redirect content into crewx q to supply the prompt body via stdin.
|
|
19
|
-
* e.g. cat brief.md | crewx q "@agent label"
|
|
20
|
-
* Stdin is ignored when running in an interactive TTY.
|
|
21
|
-
*/
|
|
22
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.handleQuery = handleQuery;
|
|
24
|
-
const sdk_1 = require("@crewx/sdk");
|
|
25
|
-
const parse_agent_message_1 = require("./parse-agent-message");
|
|
26
|
-
const parse_common_flags_1 = require("./parse-common-flags");
|
|
27
|
-
const resolve_prompt_1 = require("./resolve-prompt");
|
|
28
|
-
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
29
|
-
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
30
|
-
const write_output_1 = require("./write-output");
|
|
31
|
-
/**
|
|
32
|
-
* Handle `crewx query <agentRef> <message>` command.
|
|
33
|
-
*
|
|
34
|
-
* Default output: raw agent response only (stdout).
|
|
35
|
-
* --verbose: debug info written to stderr, response to stdout.
|
|
36
|
-
*/
|
|
37
|
-
async function handleQuery(args) {
|
|
38
|
-
const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
39
|
-
const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
|
|
40
|
-
// No @mention → default to @crewx agent (matches cli-bak behaviour)
|
|
41
|
-
const agentRef = parsedAgentRef || '@crewx';
|
|
42
|
-
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
43
|
-
const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
44
|
-
if (!finalMessage) {
|
|
45
|
-
console.error('Usage: crewx query [@agent] <message> [options]');
|
|
46
|
-
console.error(' crewx q [@agent] <message> [options]');
|
|
47
|
-
console.error('');
|
|
48
|
-
console.error(' @agent is optional. Defaults to @crewx when omitted.');
|
|
49
|
-
console.error(' Prompt can also be supplied via stdin pipe or --prompt-file.');
|
|
50
|
-
console.error('');
|
|
51
|
-
console.error('Examples:');
|
|
52
|
-
console.error(' crewx q "@agent hello"');
|
|
53
|
-
console.error(' cat brief.md | crewx q "@agent summarise"');
|
|
54
|
-
console.error(' crewx q "@agent label" --prompt-file=brief.md');
|
|
55
|
-
console.error('');
|
|
56
|
-
console.error('Options:');
|
|
57
|
-
console.error(' --thread <name> Conversation thread name');
|
|
58
|
-
console.error(' --provider <cli/xxx> Provider override');
|
|
59
|
-
console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
|
|
60
|
-
console.error(' Propagated to events/hooks/tracing.');
|
|
61
|
-
console.error(' Invalid JSON aborts with exit code 2.');
|
|
62
|
-
console.error(' e.g. --metadata=\'{"workflow_id":"wf-1"}\'');
|
|
63
|
-
console.error(' --verbose Debug output mode');
|
|
64
|
-
console.error(' --config/-c <path> Config file path');
|
|
65
|
-
console.error(' --output-format <fmt> Output format (json|text|stream-json)');
|
|
66
|
-
console.error(' --out/-o <path> Save result to file (stdout suppressed)');
|
|
67
|
-
console.error(' --effort <level> Model effort (high|medium|low)');
|
|
68
|
-
console.error(' -f/--prompt-file <path> Read prompt body from file');
|
|
69
|
-
console.error(' --var key=value Template variable (repeatable)');
|
|
70
|
-
console.error(' --overdrive Activate overdrive (boost) profile for this request');
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
74
|
-
// Only show exec audit span JSON in verbose mode
|
|
75
|
-
(0, sdk_1.setAuditVerbose)(verbose);
|
|
76
|
-
const crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
|
|
77
|
-
// file:// remote agent delegation is handled transparently inside Crewx.query/execute.
|
|
78
|
-
if (verbose) {
|
|
79
|
-
process.stderr.write(`📋 Task: ${finalMessage}\n`);
|
|
80
|
-
process.stderr.write(`🤖 Agent: ${agentRef}\n`);
|
|
81
|
-
if (thread)
|
|
82
|
-
process.stderr.write(`🔗 Thread: ${thread}\n`);
|
|
83
|
-
if (provider)
|
|
84
|
-
process.stderr.write(`🔌 Provider: ${provider}\n`);
|
|
85
|
-
if (outputFormat)
|
|
86
|
-
process.stderr.write(`📄 Output-format: ${outputFormat}\n`);
|
|
87
|
-
if (effort)
|
|
88
|
-
process.stderr.write(`⚡ Effort: ${effort}\n`);
|
|
89
|
-
if (overdrive)
|
|
90
|
-
process.stderr.write(`🚀 Overdrive: ON\n`);
|
|
91
|
-
process.stderr.write('─'.repeat(60) + '\n');
|
|
92
|
-
}
|
|
93
|
-
let parsedMetadata = {};
|
|
94
|
-
try {
|
|
95
|
-
parsedMetadata = (0, parse_common_flags_1.parseMetadata)(metadata);
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
99
|
-
process.stderr.write(`Error: ${msg}\n`);
|
|
100
|
-
process.exit(2);
|
|
101
|
-
}
|
|
102
|
-
let exitCode = 0;
|
|
103
|
-
try {
|
|
104
|
-
const result = await crewx.query(agentRef, finalMessage, {
|
|
105
|
-
provider,
|
|
106
|
-
effort: effort || undefined,
|
|
107
|
-
overdrive: overdrive || undefined,
|
|
108
|
-
threadId: thread,
|
|
109
|
-
metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
|
|
110
|
-
vars: Object.keys(vars).length > 0 ? vars : undefined,
|
|
111
|
-
trace: (0, inherited_trace_1.readInheritedTrace)(),
|
|
112
|
-
});
|
|
113
|
-
if (!result.ok) {
|
|
114
|
-
const errMsg = result.error?.message ?? 'Query failed';
|
|
115
|
-
console.error(errMsg);
|
|
116
|
-
(0, write_output_1.appendError)(out, errMsg);
|
|
117
|
-
exitCode = 1;
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
if (verbose) {
|
|
121
|
-
process.stderr.write(`\n📊 Results from ${agentRef}:\n`);
|
|
122
|
-
process.stderr.write('═'.repeat(60) + '\n');
|
|
123
|
-
process.stderr.write('🟢 Status: Success\n');
|
|
124
|
-
process.stderr.write(`🤖 Provider: ${result.meta.provider}\n`);
|
|
125
|
-
process.stderr.write(`⏱️ Duration: ${result.meta.durationMs}ms\n`);
|
|
126
|
-
process.stderr.write('\n📄 Response:\n');
|
|
127
|
-
process.stderr.write('─'.repeat(40) + '\n');
|
|
128
|
-
}
|
|
129
|
-
(0, write_output_1.writeResult)(out, result.data);
|
|
130
|
-
if (verbose) {
|
|
131
|
-
process.stderr.write('\n✅ Query completed successfully\n');
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
catch (err) {
|
|
136
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
137
|
-
console.error(`Error: ${errMsg}`);
|
|
138
|
-
(0, write_output_1.appendError)(out, `Error: ${errMsg}`);
|
|
139
|
-
exitCode = 1;
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
await crewx.close();
|
|
143
|
-
}
|
|
144
|
-
if (exitCode !== 0)
|
|
145
|
-
process.exit(exitCode);
|
|
146
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleQuery=Y;const j=require("@crewx/sdk");const V=require("@crewx/sdk/repository");const z=require("./parse-agent-message");const N=require("./parse-common-flags");const K=require("./resolve-recipient");const L=require("./resolve-prompt");const S=require("../bootstrap/crewx-cli");const m=require("../utils/inherited-trace");const q=require("./write-output");const t=require("./detached");const a=require("./emit-trailer");async function Y(u,r="query",n=(0,a.createDelegationEmitState)()){const D=(0,t.readDetachedMiddleHop)(u);if(D){await(0,t.runDetachedMiddle)(r,D);return}const f=(0,t.extractReceiptFlags)(u);const y=(0,t.resolveReceiptMode)({detach:f.detach,wait:f.wait,detachedRunner:(0,m.isDetachedRunner)(),agentContext:Boolean(process.env["CREWX_AGENT_ID"])});if(y.receipt){await(0,t.runDetached)(r,f.rest,y.reason,u);return}let b;try{b=(0,N.parseCommonFlags)(f.rest)}catch(e){(0,a.emitDelegationResult)({command:r,isError:true,state:n});throw e}const{thread:R,provider:k,model:E,metadata:B,verbose:g,config:H,outputFormat:I,effort:_,promptFile:Q,overdrive:M,vars:T,out:x,rest:G,to:W}=b;const i=(0,m.readInheritedTrace)();let $;let C;let d;try{({agentRef:$,message:C}=(0,z.parseAgentMessage)(G));d=await(0,L.resolvePrompt)(C,Q)}catch(e){(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});throw e}let w;try{({agentRef:w}=(0,K.resolveRecipient)({positionalRef:$,toFlag:W,agentContext:Boolean(process.env["CREWX_AGENT_ID"]),bodyForHint:d,command:r,invocationArgs:u}))}catch(e){const o=e instanceof Error?e.message:String(e);process.stderr.write(`Error: ${o}
|
|
2
|
+
`);(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});process.exit(2);return}if(!d){console.error("Usage: crewx query --to <agent> <message> [options]");console.error(" crewx q --to <agent> <message> [options]");console.error(' Human-terminal shorthand: crewx q "@agent <message>"');console.error("");console.error(" Agent calls require --to or a positional @agent recipient.");console.error(" Human terminal and cron calls default to @crewx when omitted.");console.error(" Prompt can also be supplied via stdin pipe or --prompt-file.");console.error("");console.error("Examples:");console.error(' crewx q --to agent "hello"');console.error(" crewx q --to agent -f brief.md");console.error(" Prompt files contain only the body; set the recipient separately with --to.");console.error("");console.error("Options:");console.error(" --to <agent> Explicit agent recipient");console.error(" --thread <name> Conversation thread name");console.error(" --provider <cli/xxx> Provider override");console.error(" --model <name> Model override (e.g. claude-sonnet-5)");console.error(" --metadata <json> Extra metadata (JSON object, double-quoted).");console.error(" Propagated to events/hooks/tracing.");console.error(" Invalid JSON aborts with exit code 2.");console.error(` e.g. --metadata='{"workflow_id":"wf-1"}'`);console.error(" --verbose Debug output mode");console.error(" --config/-c <path> Config file path");console.error(" --output-format <fmt> Output format (json|text|stream-json)");console.error(" --out/-o <path> Save result to file (stdout suppressed)");console.error(" --effort <level> Model effort (high|medium|low)");console.error(" -f/--prompt-file <path> Read body only from file; set recipient separately with --to");console.error(" --var key=value Template variable (repeatable)");console.error(" --overdrive Activate overdrive (boost) profile for this request");(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});process.exit(1);return}const X=H??process.env.CREWX_CONFIG??"crewx.yaml";(0,j.setAuditVerbose)(g);let A;try{A=await(0,S.createCliCrewx)(X)}catch(e){(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});throw e}if(g){process.stderr.write(`mode=sync reason=${y.reason}
|
|
3
|
+
`);process.stderr.write(`\u{1F4CB} Task: ${d}
|
|
4
|
+
`);process.stderr.write(`\u{1F916} Agent: ${w}
|
|
5
|
+
`);if(R)process.stderr.write(`\u{1F517} Thread: ${R}
|
|
6
|
+
`);if(k)process.stderr.write(`\u{1F50C} Provider: ${k}
|
|
7
|
+
`);if(E)process.stderr.write(`\u{1F9E0} Model: ${E}
|
|
8
|
+
`);if(I)process.stderr.write(`\u{1F4C4} Output-format: ${I}
|
|
9
|
+
`);if(_)process.stderr.write(`\u26A1 Effort: ${_}
|
|
10
|
+
`);if(M)process.stderr.write(`\u{1F680} Overdrive: ON
|
|
11
|
+
`);process.stderr.write("\u2500".repeat(60)+"\n")}let h={};try{h=(0,N.parseMetadata)(B)}catch(e){const o=e instanceof Error?e.message:String(e);process.stderr.write(`Error: ${o}
|
|
12
|
+
`);(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});process.exit(2);return}const J=(0,t.resolveCliTaskActor)(h);const U=(0,m.isDetachedRunner)();const P=(0,m.readRunnerAssignment)();let v;let O;let c;if(P!==void 0){const e=new V.TaskRepository;const o=(0,t.adoptAssignedTask)(e,P,U);if(o.kind==="failed"){(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});process.exit(1);return}if(o.kind==="adopted"){v=o.taskId;O=(0,t.readAssignedTaskActor)(e,o.taskId);c=(0,t.readAssignedTaskProviderAccountBinding)(e,o.taskId)}}let l;if(v===void 0){l=(0,j.admitDurableTask)(`direct-cli:${r}`);if(!l.ok){(0,t.reportAdmissionBlocked)(l);(0,a.emitDelegationResult)({command:r,trace:i,isError:true,state:n});process.exit(1);return}}const F=c?(0,t.mergeAssignedTaskProviderAccountMetadata)(h,c):h;let p=0;let s;try{try{s=await A.query(w,d,{provider:c?.provider??k,model:E,effort:_||void 0,overdrive:M||void 0,threadId:R,taskId:v,actor:v===void 0?J:O,metadata:Object.keys(F).length>0?F:void 0,vars:Object.keys(T).length>0?T:void 0,trace:i,...(0,t.buildRecordedProviderAccountOptions)(c),...c&&(0,t.shouldReplayRecordedAntigravityAcp)(c)?{providerAccountReplay:true}:{}});if(!s.ok){const e=s.error?.message??"Query failed";console.error(e);(0,q.appendError)(x,e);p=1}else{if(g){process.stderr.write(`
|
|
13
|
+
\u{1F4CA} Results from ${w}:
|
|
14
|
+
`);process.stderr.write("\u2550".repeat(60)+"\n");process.stderr.write("\u{1F7E2} Status: Success\n");process.stderr.write(`\u{1F916} Provider: ${s.meta.provider}
|
|
15
|
+
`);process.stderr.write(`\u23F1\uFE0F Duration: ${s.meta.durationMs}ms
|
|
16
|
+
`);process.stderr.write("\n\u{1F4C4} Response:\n");process.stderr.write("\u2500".repeat(40)+"\n")}(0,q.writeResult)(x,s.data);if(g){process.stderr.write("\n\u2705 Query completed successfully\n")}}}catch(e){const o=e instanceof Error?e.message:String(e);console.error(`Error: ${o}`);(0,q.appendError)(x,`Error: ${o}`);p=1}finally{try{await A.close()}catch(e){(0,a.emitDelegationResult)({command:r,trace:i,taskId:s?.meta.taskId,agentId:s?.meta.agentId,isError:true,state:n});throw e}}}finally{if(l?.ok)l.release()}(0,a.emitDelegationResult)({command:r,trace:i,taskId:s?.meta.taskId,agentId:s?.meta.agentId,isError:p!==0||s?.ok===false,state:n});if(p!==0)process.exit(p)}
|
|
@@ -1,31 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* CLI command registry — SSOT for commands handled by the CLI engine.
|
|
4
|
-
*
|
|
5
|
-
* Consumed by:
|
|
6
|
-
* - main.ts dispatch (to avoid switch/case literal drift)
|
|
7
|
-
* - bin/__tests__/crewx-entrypoint.test.ts (SSOT assertion vs CLI_SUBCOMMANDS)
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.NOT_YET_MIGRATED = exports.BUILTIN_COMMAND_NAMES = exports.KNOWN_COMMANDS = void 0;
|
|
11
|
-
/** Core commands handled by the main.ts switch/case or hook routing. */
|
|
12
|
-
exports.KNOWN_COMMANDS = new Set([
|
|
13
|
-
'q', 'query',
|
|
14
|
-
'x', 'execute',
|
|
15
|
-
'agent',
|
|
16
|
-
'ps', 'kill', 'result', 'log', 'restart',
|
|
17
|
-
'doctor', 'init',
|
|
18
|
-
'db',
|
|
19
|
-
'help',
|
|
20
|
-
'slack', 'slack:files',
|
|
21
|
-
'hook', 'hook-dispatch',
|
|
22
|
-
]);
|
|
23
|
-
/** Built-in tool commands routed via handleBuiltin(). */
|
|
24
|
-
exports.BUILTIN_COMMAND_NAMES = new Set([
|
|
25
|
-
'memory', 'search', 'doc', 'wbs', 'cron', 'workflow', 'skill', 'dreaming',
|
|
26
|
-
'wi', 'chromex',
|
|
27
|
-
]);
|
|
28
|
-
/** Commands not yet migrated from cli-bak — show a migration message. */
|
|
29
|
-
exports.NOT_YET_MIGRATED = new Set([
|
|
30
|
-
'template', 'templates', 'chat', 'mcp',
|
|
31
|
-
]);
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.NOT_YET_MIGRATED=exports.BUILTIN_COMMAND_NAMES=exports.KNOWN_COMMANDS=void 0;exports.KNOWN_COMMANDS=new Set(["q","query","x","execute","agent","history","ps","stop","kill","result","log","restart","doctor","init","db","help","shortcut","ai-account","publish","slack","slack:files","hook","hook-dispatch"]);exports.BUILTIN_COMMAND_NAMES=new Set(["memory","search","doc","wbs","cron","workflow","skill","dreaming","wi","chromex","notify","app"]);exports.NOT_YET_MIGRATED=new Set(["template","templates","chat","mcp"]);
|
|
@@ -1,54 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* Supports three input channels:
|
|
6
|
-
* 1. --prompt-file <path> — read content from a file
|
|
7
|
-
* 2. stdin pipe/redirect — read from process.stdin when not a TTY
|
|
8
|
-
* 3. argv prompt — positional argument passed directly on the command line
|
|
9
|
-
*
|
|
10
|
-
* When multiple sources are present, argv is used as a short label/prefix
|
|
11
|
-
* and the file/stdin content is appended after a blank line.
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.readStdin = readStdin;
|
|
15
|
-
exports.resolvePrompt = resolvePrompt;
|
|
16
|
-
const fs_1 = require("fs");
|
|
17
|
-
/**
|
|
18
|
-
* Read all bytes from stdin (pipe or redirect).
|
|
19
|
-
* Returns empty string when stdin is a TTY (interactive terminal).
|
|
20
|
-
*/
|
|
21
|
-
async function readStdin() {
|
|
22
|
-
if (process.stdin.isTTY)
|
|
23
|
-
return '';
|
|
24
|
-
const chunks = [];
|
|
25
|
-
for await (const chunk of process.stdin)
|
|
26
|
-
chunks.push(chunk);
|
|
27
|
-
return Buffer.concat(chunks).toString('utf8').trimEnd();
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Resolve the final prompt from argv, stdin pipe, or --prompt-file.
|
|
31
|
-
*
|
|
32
|
-
* Priority:
|
|
33
|
-
* 1. promptFile is specified → read file content
|
|
34
|
-
* 2. argv is present → use argv (stdin is NOT read — prevents hang in child processes)
|
|
35
|
-
* 3. argv is empty, no promptFile → read stdin pipe/redirect
|
|
36
|
-
* 4. argv + promptFile both present → `${argv}\n\n${fileContent}`
|
|
37
|
-
* 5. Neither present → return '' (caller decides error handling)
|
|
38
|
-
*
|
|
39
|
-
* @param _readStdin - injectable stdin reader, defaults to the module-level
|
|
40
|
-
* readStdin. Exposed as a parameter so unit tests can substitute a stub
|
|
41
|
-
* without fighting ESM module binding rules.
|
|
42
|
-
*/
|
|
43
|
-
async function resolvePrompt(argvPrompt, promptFile, _readStdin = readStdin) {
|
|
44
|
-
let external = '';
|
|
45
|
-
if (promptFile) {
|
|
46
|
-
external = (0, fs_1.readFileSync)(promptFile, 'utf8').trimEnd();
|
|
47
|
-
}
|
|
48
|
-
else if (!argvPrompt) {
|
|
49
|
-
external = (await _readStdin()).trimEnd();
|
|
50
|
-
}
|
|
51
|
-
if (argvPrompt && external)
|
|
52
|
-
return `${argvPrompt}\n\n${external}`;
|
|
53
|
-
return external || argvPrompt;
|
|
54
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.readStdin=f;exports.resolvePrompt=o;const s=require("fs");function u(n){const t=(0,s.readFileSync)(n);if(t.length>=3&&t[0]===239&&t[1]===187&&t[2]===191){return t.subarray(3).toString("utf8")}if(t.length>=2&&t[0]===255&&t[1]===254){return t.subarray(2).toString("utf16le")}if(t.length>=2&&t[0]===254&&t[1]===255){const r=t.subarray(2);for(let e=0;e+1<r.length;e+=2){const i=r[e];r[e]=r[e+1];r[e+1]=i}return r.toString("utf16le")}return t.toString("utf8")}async function f(){if(process.stdin.isTTY)return"";const n=[];for await(const t of process.stdin)n.push(t);return Buffer.concat(n).toString("utf8").trimEnd()}async function o(n,t,r=f){let e="";if(t){e=u(t).trimEnd()}else if(!n){e=(await r()).trimEnd()}if(n&&e)return`${n}
|
|
2
|
+
|
|
3
|
+
${e}`;return e||n}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ResolveRecipientOptions {
|
|
2
|
+
positionalRef?: string;
|
|
3
|
+
toFlag?: string;
|
|
4
|
+
agentContext: boolean;
|
|
5
|
+
bodyForHint?: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
invocationArgs?: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class RecipientResolutionError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveRecipient(options: ResolveRecipientOptions): {
|
|
13
|
+
agentRef: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RecipientResolutionError=void 0;exports.resolveRecipient=d;class r extends Error{constructor(t){super(t);this.name="RecipientResolutionError"}}exports.RecipientResolutionError=r;function d(e){const t=c(e.toFlag,true);const n=c(e.positionalRef,false);if(t&&n&&t!==n){throw new r(`Recipient was specified twice: --to ${t.slice(1)} conflicts with positional ${n}.`)}const i=t??n;if(i)return{agentRef:i};if(!e.agentContext)return{agentRef:"@crewx"};const s=e.bodyForHint?.match(/^@(\S+)/u)?.[1];const u=s??"<agent-id>";const a=e.command??"query";const o=(e.invocationArgs??[]).map(l).join(" ");const f=`crewx ${a} --to ${u}${o?` ${o}`:""}`;throw new r(`No recipient was specified. Agent calls must set one explicitly; nothing was run.
|
|
2
|
+
Retry command: ${f}
|
|
3
|
+
To ask the built-in assistant on purpose, use --to crewx.`)}function c(e,t){if(e===void 0)return void 0;const n=e.trim().replace(/^@/u,"");if(!n){if(t)throw new r("--to requires an agent id.");return void 0}return`@${n}`}function l(e){if(!/\s/u.test(e))return e;return`"${e.replaceAll('"','\\"')}"`}
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
* crewx restart <task-id>
|
|
15
15
|
*
|
|
16
16
|
* Behavior:
|
|
17
|
-
* - Only tasks with status='failed' can be restarted
|
|
17
|
+
* - Only tasks with status='failed' can be restarted, except a run whose end was not
|
|
18
|
+
* observed (`terminalReason: 'runner_lost'`): it may still be running, so it is refused
|
|
19
|
+
* by default (same decision as the SDK's `isTaskRetryableByDefault`).
|
|
18
20
|
* - A new taskId is generated; the original task row is never mutated.
|
|
19
21
|
* - metadata.restartedFromTaskId (+ retriedFromTaskId for compat) is recorded.
|
|
20
22
|
* - The Web UI `TSK.RETRY` system-message prefix is reused verbatim.
|
package/dist/commands/restart.js
CHANGED
|
@@ -1,162 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* - A new taskId is generated; the original task row is never mutated.
|
|
20
|
-
* - metadata.restartedFromTaskId (+ retriedFromTaskId for compat) is recorded.
|
|
21
|
-
* - The Web UI `TSK.RETRY` system-message prefix is reused verbatim.
|
|
22
|
-
* - stdout carries the agent final response; guidance/errors go to stderr.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.handleRestart = handleRestart;
|
|
26
|
-
const sdk_1 = require("@crewx/sdk");
|
|
27
|
-
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
28
|
-
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
29
|
-
/**
|
|
30
|
-
* Build the retry system-message prefix.
|
|
31
|
-
* Intentionally identical to the server `ThreadService.retryTask()` prefix so
|
|
32
|
-
* stored conversations / parsers stay compatible. `type="retry"` is preserved.
|
|
33
|
-
*/
|
|
34
|
-
function buildRetryPrefix(originalTaskId) {
|
|
35
|
-
return (`<crewx_system_message type="retry">\n` +
|
|
36
|
-
`Retrying a failed task.\n` +
|
|
37
|
-
`You must run \`crewx dreaming --task=${originalTaskId}\` to review where it stopped before continuing.\n` +
|
|
38
|
-
`</crewx_system_message>\n\n`);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Recover the effective provider from a task row's `metadata` JSON.
|
|
42
|
-
* The SDK persists the resolved provider as `metadata.provider`. Returns
|
|
43
|
-
* the string when present and non-empty, otherwise `undefined` so the
|
|
44
|
-
* agent's configured provider default is used.
|
|
45
|
-
*/
|
|
46
|
-
function parseTaskMetadata(metadata) {
|
|
47
|
-
if (!metadata)
|
|
48
|
-
return {};
|
|
49
|
-
try {
|
|
50
|
-
const parsed = JSON.parse(metadata);
|
|
51
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
52
|
-
? parsed
|
|
53
|
-
: {};
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return {};
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function extractProvider(metadata) {
|
|
60
|
-
const provider = metadata.provider;
|
|
61
|
-
return typeof provider === 'string' && provider.length > 0 ? provider : undefined;
|
|
62
|
-
}
|
|
63
|
-
async function handleRestart(args) {
|
|
64
|
-
const verbose = args.includes('--verbose');
|
|
65
|
-
const taskId = args.find((a) => !a.startsWith('--'));
|
|
66
|
-
if (!taskId) {
|
|
67
|
-
process.stderr.write('Usage: crewx restart <task-id>\n');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const repo = new sdk_1.TaskRepository();
|
|
72
|
-
const original = repo.getTask(taskId);
|
|
73
|
-
if (!original) {
|
|
74
|
-
process.stderr.write(`Error: Task not found: ${taskId}\n`);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (original.status !== 'failed') {
|
|
79
|
-
process.stderr.write(`Error: Task ${taskId} is not in failed state (current: ${original.status ?? 'unknown'}). ` +
|
|
80
|
-
`Only failed tasks can be restarted.\n`);
|
|
81
|
-
process.exit(1);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (!original.prompt) {
|
|
85
|
-
process.stderr.write(`Error: Task ${taskId} has no prompt to restart.\n`);
|
|
86
|
-
process.exit(1);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (!original.agent_id) {
|
|
90
|
-
process.stderr.write(`Error: Task ${taskId} has no agent to restart.\n`);
|
|
91
|
-
process.exit(1);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
const mode = original.mode === 'query' ? 'query' : 'execute';
|
|
95
|
-
const agentRef = `@${original.agent_id}`;
|
|
96
|
-
const newTaskId = (0, sdk_1.generateId)('tsk');
|
|
97
|
-
const restartPrompt = `${buildRetryPrefix(taskId)}${original.prompt}`;
|
|
98
|
-
// model: reuse the original task row value when present, otherwise fall back
|
|
99
|
-
// to the agent's configured default (resolved inside Crewx).
|
|
100
|
-
const model = original.model ?? undefined;
|
|
101
|
-
// provider: recovered from metadata.provider (SDK-persisted). Falls back to
|
|
102
|
-
// the agent's configured provider when absent. This preserves a
|
|
103
|
-
// `crewx x --provider ...` choice across restart.
|
|
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';
|
|
108
|
-
(0, sdk_1.setAuditVerbose)(verbose);
|
|
109
|
-
if (verbose) {
|
|
110
|
-
process.stderr.write(`🔁 Restart: ${taskId} → ${newTaskId}\n`);
|
|
111
|
-
process.stderr.write(`🤖 Agent: ${agentRef} Mode: ${mode}\n`);
|
|
112
|
-
if (original.thread_id)
|
|
113
|
-
process.stderr.write(`🔗 Thread: ${original.thread_id}\n`);
|
|
114
|
-
process.stderr.write('─'.repeat(60) + '\n');
|
|
115
|
-
}
|
|
116
|
-
const crewx = await (0, crewx_cli_1.createCliCrewx)();
|
|
117
|
-
const sdkOptions = {
|
|
118
|
-
taskId: newTaskId,
|
|
119
|
-
threadId: original.thread_id ?? undefined,
|
|
120
|
-
model,
|
|
121
|
-
provider,
|
|
122
|
-
...(originalWasOverdrive ? { overdrive: { mode: originalOverdriveMode } } : {}),
|
|
123
|
-
metadata: {
|
|
124
|
-
restartedFromTaskId: taskId,
|
|
125
|
-
// Back-compat / search convenience: mirror the Web UI metadata key.
|
|
126
|
-
retriedFromTaskId: taskId,
|
|
127
|
-
...(originalWasOverdrive ? {
|
|
128
|
-
overdrive: true,
|
|
129
|
-
overdriveState: originalOverdriveMode,
|
|
130
|
-
overdriveMode: mode,
|
|
131
|
-
} : {}),
|
|
132
|
-
},
|
|
133
|
-
trace: (0, inherited_trace_1.readInheritedTrace)(),
|
|
134
|
-
};
|
|
135
|
-
let exitCode = 0;
|
|
136
|
-
try {
|
|
137
|
-
const result = mode === 'query'
|
|
138
|
-
? await crewx.query(agentRef, restartPrompt, sdkOptions)
|
|
139
|
-
: await crewx.execute(agentRef, restartPrompt, sdkOptions);
|
|
140
|
-
if (result.ok) {
|
|
141
|
-
process.stdout.write(result.data + '\n');
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
const errMsg = result.error?.message ?? 'Restart failed';
|
|
145
|
-
const resultTaskId = result.meta?.taskId ?? newTaskId;
|
|
146
|
-
process.stderr.write(`Error: ${errMsg}\n`);
|
|
147
|
-
process.stderr.write(`taskId=${resultTaskId}\n`);
|
|
148
|
-
exitCode = 1;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
153
|
-
process.stderr.write(`Error: ${errMsg}\n`);
|
|
154
|
-
process.stderr.write(`taskId=${newTaskId}\n`);
|
|
155
|
-
exitCode = 1;
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
await crewx.close();
|
|
159
|
-
}
|
|
160
|
-
if (exitCode !== 0)
|
|
161
|
-
process.exit(exitCode);
|
|
162
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleRestart=I;const n=require("@crewx/sdk");const T=require("../bootstrap/crewx-cli");const _=require("../utils/inherited-trace");const u=require("./detached");function b(o){return`<crewx_system_message type="retry">
|
|
2
|
+
Retrying a failed task.
|
|
3
|
+
You must run \`crewx dreaming --task=${o}\` to review where it stopped before continuing.
|
|
4
|
+
</crewx_system_message>
|
|
5
|
+
|
|
6
|
+
`}function R(o){if(!o)return{};try{const t=JSON.parse(o);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function A(o){const t=o.provider;return typeof t==="string"&&t.length>0?t:void 0}async function I(o){const t=o.includes("--verbose");const r=o.find(s=>!s.startsWith("--"));if(!r){process.stderr.write("Usage: crewx restart <task-id>\n");process.exit(1);return}const h=new n.TaskRepository;const e=h.getTask(r);if(!e){process.stderr.write(`Error: Task not found: ${r}
|
|
7
|
+
`);process.exit(1);return}if(!(0,n.isTaskRetryableByDefault)(e)){if((0,n.normalizeTaskStatus)(e)==="failed"){process.stderr.write(`Error: Task ${r} was not restarted: the end of the run was not observed (runner lost), so it may have done part of the work or may still be running. Check it with \`crewx log ${r}\` or \`crewx ps\` before running it again.
|
|
8
|
+
`)}else{process.stderr.write(`Error: Task ${r} is not in failed state (current: ${e.status??"unknown"}). Only failed tasks can be restarted.
|
|
9
|
+
`)}process.exit(1);return}if(!e.prompt){process.stderr.write(`Error: Task ${r} has no prompt to restart.
|
|
10
|
+
`);process.exit(1);return}if(!e.agent_id){process.stderr.write(`Error: Task ${r} has no agent to restart.
|
|
11
|
+
`);process.exit(1);return}const p=e.mode==="query"?"query":"execute";const l=`@${e.agent_id}`;const a=(0,n.generateId)("tsk");const g=`${b(r)}${e.prompt}`;const m=e.model??void 0;const i=R(e.metadata);const d=(0,u.readTaskProviderAccountBinding)(i);const x=d.provider??A(i);const k=i.overdrive===true;const v=i.overdriveState==="latch"?"latch":"count";(0,n.setAuditVerbose)(t);if(t){process.stderr.write(`\u{1F501} Restart: ${r} \u2192 ${a}
|
|
12
|
+
`);process.stderr.write(`\u{1F916} Agent: ${l} Mode: ${p}
|
|
13
|
+
`);if(e.thread_id)process.stderr.write(`\u{1F517} Thread: ${e.thread_id}
|
|
14
|
+
`);process.stderr.write("\u2500".repeat(60)+"\n")}const f=await(0,T.createCliCrewx)();const y={taskId:a,threadId:e.thread_id??void 0,model:m,provider:x,...(0,u.buildRecordedProviderAccountOptions)(d),...(0,u.shouldReplayRecordedAntigravityAcp)(d)?{providerAccountReplay:true}:{},...k?{overdrive:{mode:v}}:{},metadata:(0,u.mergeAssignedTaskProviderAccountMetadata)({restartedFromTaskId:r,retriedFromTaskId:r,...k?{overdrive:true,overdriveState:v,overdriveMode:p}:{}},d),trace:(0,_.readInheritedTrace)()};let c=0;try{const s=p==="query"?await f.query(l,g,y):await f.execute(l,g,y);if(s.ok){process.stdout.write(s.data+"\n")}else{const w=s.error?.message??"Restart failed";const $=s.meta?.taskId??a;process.stderr.write(`Error: ${w}
|
|
15
|
+
`);process.stderr.write(`taskId=${$}
|
|
16
|
+
`);c=1}}catch(s){const w=s instanceof Error?s.message:String(s);process.stderr.write(`Error: ${w}
|
|
17
|
+
`);process.stderr.write(`taskId=${a}
|
|
18
|
+
`);c=1}finally{await f.close()}if(c!==0)process.exit(c)}
|
|
@@ -3,8 +3,13 @@
|
|
|
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=<seconds> Poll (1s interval) up to the given
|
|
9
|
+
* number of seconds for
|
|
10
|
+
* the task to leave 'pending'/'running'. Exit 124 on
|
|
11
|
+
* timeout. --wait=0 behaves like no --wait
|
|
12
|
+
* (single immediate check).
|
|
13
|
+
* crewx result List recent tasks (latest 10)
|
|
9
14
|
*/
|
|
10
15
|
export declare function handleResult(args: string[]): Promise<void>;
|
package/dist/commands/result.js
CHANGED
|
@@ -1,70 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* crewx result handler.
|
|
4
|
-
* Retrieves the result of a completed task by its ID.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* crewx result <task-id> Print raw result
|
|
8
|
-
* crewx result <task-id> --json Print full task record as JSON
|
|
9
|
-
* crewx result List recent tasks (latest 10)
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.handleResult = handleResult;
|
|
13
|
-
const repository_1 = require("@crewx/sdk/repository");
|
|
14
|
-
function statusIcon(status) {
|
|
15
|
-
switch (status) {
|
|
16
|
-
case 'running': return '⏳';
|
|
17
|
-
case 'success': return '✅';
|
|
18
|
-
case 'failed': return '❌';
|
|
19
|
-
default: return '❓';
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
async function handleResult(args) {
|
|
23
|
-
const jsonMode = args.includes('--json');
|
|
24
|
-
const taskId = args.find(a => !a.startsWith('--'));
|
|
25
|
-
const repo = new repository_1.TaskRepository();
|
|
26
|
-
if (!taskId) {
|
|
27
|
-
const all = repo.getAllTasks();
|
|
28
|
-
const recent = all.slice(0, 10);
|
|
29
|
-
if (recent.length === 0) {
|
|
30
|
-
console.log('No tasks found.');
|
|
31
|
-
console.log('Tip: Run `crewx query` or `crewx execute` to start a task.');
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
console.log('Recent Tasks (latest 10)\n');
|
|
35
|
-
recent.forEach((task, idx) => {
|
|
36
|
-
const icon = statusIcon(task.status);
|
|
37
|
-
console.log(`${idx + 1}. ${icon} ${task.id}`);
|
|
38
|
-
console.log(` Agent: ${task.agent_id ?? '—'} Mode: ${task.mode ?? '—'}`);
|
|
39
|
-
console.log(` Started: ${new Date(task.started_at).toLocaleString()}`);
|
|
40
|
-
if (task.completed_at) {
|
|
41
|
-
console.log(` Completed: ${new Date(task.completed_at).toLocaleString()}`);
|
|
42
|
-
}
|
|
43
|
-
console.log('');
|
|
44
|
-
});
|
|
45
|
-
console.log('Tip: Run `crewx result <task-id>` to see full output.');
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const task = repo.getTask(taskId);
|
|
49
|
-
if (!task) {
|
|
50
|
-
console.error(`Error: Task not found: ${taskId}`);
|
|
51
|
-
process.exit(1);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (jsonMode) {
|
|
55
|
-
console.log(JSON.stringify(task, null, 2));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (task.status === 'running') {
|
|
59
|
-
console.error(`Task ${taskId} is still running.`);
|
|
60
|
-
console.error(`Use \`crewx kill ${taskId}\` to stop it.`);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (task.status === 'failed') {
|
|
65
|
-
console.error(`Task ${taskId} failed: ${task.error ?? 'unknown error'}`);
|
|
66
|
-
process.exit(1);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
console.log(task.result ?? '');
|
|
70
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleResult=M;const g=require("@crewx/sdk");const w=require("@crewx/sdk/repository");const d=require("./cal");const x=1e3;const f=1e4;function $(t){return t.status==="failed"&&(0,w.readTaskTerminalReason)(t)==="runner_lost"}function T(t){if($(t))return"\u26A0\uFE0F";switch(t.status){case"pending":return"\u{1F553}";case"running":return"\u23F3";case"success":return"\u2705";case"failed":return"\u274C";case"stopped":return"\u23F9";default:return"\u2753"}}function p(t){return t==="pending"||t==="running"}function _(t){return new Promise(s=>setTimeout(s,t))}function R(t){switch(t){case"pending":return"crewx.result-pending";case"running":return"crewx.result-running";case"success":return"crewx.result-done";case"failed":case"stopped":return"crewx.result-terminal-abnormal";default:return"crewx.result"}}function c(t,s){const r={taskId:t.id};if(t.agent_id)r.agent=t.agent_id;if(t.thread_id)r.thread=t.thread_id;if(p(t.status)){r.wait=String((0,d.suggestWaitSeconds)({startedAt:t.started_at,lastWaitSeconds:s}))}(0,d.writeCalFooter)({commandId:R(t.status),params:r})}function S(t,s=Date.now()){const r=Date.parse(t);const n=Number.isFinite(r)?Math.max(0,Math.floor((s-r)/1e3)):0;const i=Math.floor(n/3600);const u=Math.floor(n%3600/60);const e=n%60;if(i>0)return`${i}h ${u}m ${e}s`;if(u>0)return`${u}m ${e}s`;return`${e}s`}function k(t){const s=t.find(n=>n.startsWith("--wait="));if(s===void 0)return void 0;const r=Number(s.slice("--wait=".length));return Number.isFinite(r)&&r>=0?r:0}async function M(t){const s=t.includes("--json");const r=k(t);const n=t.find(o=>!o.startsWith("--"));const i=new w.TaskRepository;const u=await i.reapOrphanedTasks({tickIntervalMs:f});if(u>0)console.error(`Reaped ${u} orphaned task(s)`);if(!n){const o=i.getAllTasks();const l=o.slice(0,10);if(l.length===0){console.log("No tasks found.");console.log("Tip: Run `crewx query` or `crewx execute` to start a task.");return}console.log("Recent Tasks (latest 10)\n");l.forEach((a,m)=>{const h=T(a);console.log(`${m+1}. ${h} ${a.id}`);console.log(` Agent: ${a.agent_id??"\u2014"} Mode: ${a.mode??"\u2014"}`);console.log(` Started: ${(0,g.formatDisplayTimestamp)(new Date(a.started_at))}`);if(a.completed_at){console.log(` Completed: ${(0,g.formatDisplayTimestamp)(new Date(a.completed_at))}`)}console.log("")});console.log("Tip: Run `crewx result <task-id>` to see full output.");if(!s)c(l[0]);return}let e=i.getTask(n);if(!e){console.error(`Error: Task not found: ${n}`);process.exit(1);return}if(r!==void 0&&r>0&&p(e.status)){const o=Date.now()+r*1e3;let l=Date.now();while(e&&p(e.status)){if(Date.now()>=o){console.error(`Task ${n} is still ${e.status} (waited ${r}s; running for ${S(e.started_at)}). Not stalled \u2014 check again with a longer wait.`);c(e,r);process.exit(124);return}await _(Math.min(x,Math.max(0,o-Date.now())));if(Date.now()-l>=f){const a=await i.reapOrphanedTasks({tickIntervalMs:f});if(a>0)console.error(`Reaped ${a} orphaned task(s)`);l=Date.now()}e=i.getTask(n);if(!e){console.error(`Error: Task not found: ${n}`);process.exit(1);return}}}if(s){console.log(JSON.stringify(e,null,2));return}if(e.status==="pending"){console.error(`\u{1F553} Task ${n} is pending (waiting to start \u2014 runner has not adopted the task yet).`);const o=(0,d.suggestWaitSeconds)({startedAt:e.started_at,lastWaitSeconds:r});console.error(`Use \`crewx result ${n} --wait=${o}\` to wait for completion.`);c(e,r);process.exit(1);return}if(e.status==="running"){console.error(`Task ${n} is still running.`);const o=(0,d.suggestWaitSeconds)({startedAt:e.started_at,lastWaitSeconds:r});console.error(`Use \`crewx result ${n} --wait=${o}\` to wait longer or \`crewx log ${n}\` to inspect progress.`);c(e,r);process.exit(1);return}if(e.status==="stopped"){if(e.result!==null&&e.result!==void 0){console.log(e.result)}console.error(`\u23F9 Task ${n} was stopped by user: ${e.error??"no further details"}.`);c(e);process.exit(1);return}if($(e)){console.error(`\u26A0\uFE0F Task ${n} runner lost before completion: ${e.error??"no further details"}.`);c(e);process.exit(1);return}if(e.status==="failed"){console.error(`Task ${n} failed: ${e.error??"unknown error"}`);c(e);process.exit(1);return}console.log(e.result??"");c(e)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleShortcut(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.handleShortcut=b;const c=require("@crewx/sdk/desktop");const h=require("./parse-common-flags");const i="NOT_WINDOWS: Desktop shortcuts are only supported on Windows.";function a(e,t){let o=false;let s=false;for(const r of e){if(r==="--json"){o=true;continue}if(r==="--force"&&t){s=true;continue}throw new h.UnknownOptionError(`Unknown option: ${r}`)}return{json:o,force:s}}function f(e){process.stderr.write(`[shortcut] ${e.message}
|
|
2
|
+
`)}function n(e){console.log(JSON.stringify(e))}function l(e,t){const o=e instanceof Error?e.message:String(e);if(t){n({success:false,error:o})}else{console.error(`\u2717 ${o}`)}process.exit(1)}function u(e){if(e){n({success:false,supported:false,state:"unsupported",error:i})}else{console.error(`\u2717 ${i}`)}process.exit(1)}function p(e){const t=e.errors.find(s=>s.startsWith("SUPERSEDED:"));if(e.state==="superseded"||t){return t??"Installed shortcut belongs to a newer CrewX version; refusing to modify it."}const o=e.errors.find(s=>s.startsWith("GLOBAL_INSTALL_UNCONFIRMED:"));if(!e.installedGlobal&&o){return o}if(e.errors.length>0){return e.errors[0]}return null}const w=new Set(["declined","not-installed"]);function g(e){if(w.has(e.state)){return null}const t=e.errors.find(o=>o.startsWith("SUPERSEDED:"));if(e.state==="superseded"||t){return t??"Installed shortcut belongs to a newer CrewX version; nothing was removed."}if(e.state==="foreign"){const o=e.errors.find(s=>s.startsWith("NSIS_PRESENT:"));return o??"Existing Desktop shortcut is not managed by CrewX; nothing was removed."}if(e.errors.length>0){return e.errors[0]}return`CrewX desktop shortcut could not be removed (state: ${e.state}).`}function S(e){switch(e.state){case"unsupported":console.log("Desktop shortcuts are only supported on Windows.");break;case"not-installed":console.log("No CrewX desktop shortcut installed yet.");console.log("Run `crewx shortcut install` to create one.");break;case"declined":console.log("CrewX desktop shortcut setup was previously dismissed.");console.log("Run `crewx shortcut install` to create one.");break;case"installed":console.log("\u2713 CrewX desktop shortcut is installed and up to date.");if(e.shortcutPath)console.log(` Shortcut: ${e.shortcutPath}`);break;case"stale":console.log("\u26A0 CrewX desktop shortcut needs an update.");console.log("Run `crewx shortcut install` to refresh it.");break;case"foreign":console.log("\u26A0 A Desktop shortcut exists that CrewX does not manage.");console.log("Run `crewx shortcut install --force` to replace it.");break;case"superseded":console.log("\u26A0 The installed shortcut belongs to a newer CrewX version than the one running.");console.log("Update CrewX before touching the shortcut.");break}for(const t of e.errors){console.log(` note: ${t}`)}}async function k(e){const{json:t}=a(e,false);let o;try{o=await(0,c.getShortcutStatus)()}catch(s){l(s,t)}if(t){n(o);return}S(o)}async function m(e){const{json:t,force:o}=a(e,true);let s;try{s=await(0,c.installShortcut)({force:o,onProgress:f})}catch(d){l(d,t)}if(!s.supported){u(t)}const r=p(s);if(r){if(t){n({...s,success:false})}else{console.error(`\u2717 ${r}`)}process.exit(1)}if(t){n({...s,success:true});return}if(s.changed){console.log('\u2713 CrewX desktop shortcut installed. Double-click "CrewX" on your Desktop to launch it.')}else{console.log('\u2713 CrewX desktop shortcut is already up to date. Double-click "CrewX" on your Desktop to launch it.')}if(s.shortcutPath)console.log(` Shortcut: ${s.shortcutPath}`)}async function y(e){const{json:t}=a(e,false);let o;try{o=await(0,c.uninstallShortcut)()}catch(r){l(r,t)}if(!o.supported){u(t)}const s=g(o);if(s){if(t){n({...o,success:false})}else{console.error(`\u2717 ${s}`);for(const r of o.errors){if(r!==s)console.error(` note: ${r}`)}}process.exit(1)}if(t){n({...o,success:true});return}console.log("\u2713 CrewX desktop shortcut removed.")}function C(){console.log(`
|
|
3
|
+
crewx shortcut \u2014 manage the Windows Desktop shortcut for CrewX
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
crewx shortcut status [--json]
|
|
7
|
+
crewx shortcut install [--force] [--json]
|
|
8
|
+
crewx shortcut uninstall [--json]
|
|
9
|
+
|
|
10
|
+
Options:
|
|
11
|
+
--json Print machine-readable JSON to stdout (progress/log always go to stderr)
|
|
12
|
+
--force (install only) Overwrite a Desktop shortcut CrewX does not manage.
|
|
13
|
+
Never overwrites a shortcut created by a newer CrewX version.
|
|
14
|
+
|
|
15
|
+
Notes:
|
|
16
|
+
Windows only. On macOS/Linux, \`status\` reports state "unsupported" (exit 0);
|
|
17
|
+
\`install\`/\`uninstall\` exit 1 with no changes made.
|
|
18
|
+
`.trim())}async function b(e){const t=e[0];if(!t||t==="help"||t==="--help"||t==="-h"){C();return}const o=e.slice(1);switch(t){case"status":return k(o);case"install":return m(o);case"uninstall":return y(o);default:console.error(`Unknown shortcut subcommand: ${t}`);console.error("Run `crewx shortcut help` for usage.");process.exit(1)}}
|