@crewx/cli 0.9.0-rc.1 → 0.9.0-rc.100
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 +58 -0
- package/dist/bootstrap/codex-writable-roots.js +113 -0
- package/dist/bootstrap/crewx-cli.js +8 -1
- package/dist/builtin.js +1 -0
- package/dist/commands/agent.js +0 -58
- package/dist/commands/cal.d.ts +15 -0
- package/dist/commands/cal.js +44 -0
- package/dist/commands/db.d.ts +2 -0
- package/dist/commands/db.js +381 -1
- package/dist/commands/detached.d.ts +65 -0
- package/dist/commands/detached.js +507 -0
- package/dist/commands/doctor.d.ts +53 -0
- package/dist/commands/doctor.js +391 -21
- package/dist/commands/emit-trailer.d.ts +25 -0
- package/dist/commands/emit-trailer.js +33 -0
- package/dist/commands/execute.d.ts +7 -4
- package/dist/commands/execute.js +121 -16
- package/dist/commands/hook/command-marker.d.ts +2 -0
- package/dist/commands/hook/command-marker.js +5 -0
- package/dist/commands/hook/install.d.ts +0 -1
- package/dist/commands/hook/install.js +60 -63
- package/dist/commands/hook/status.js +3 -3
- package/dist/commands/hook/uninstall.js +2 -2
- package/dist/commands/init.js +22 -1
- package/dist/commands/kill.d.ts +2 -8
- package/dist/commands/kill.js +6 -47
- 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.d.ts +2 -2
- package/dist/commands/ps.js +69 -11
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.js +303 -0
- package/dist/commands/query.d.ts +5 -1
- package/dist/commands/query.js +114 -11
- package/dist/commands/registry.js +4 -2
- package/dist/commands/restart.js +20 -6
- package/dist/commands/result.d.ts +8 -3
- package/dist/commands/result.js +139 -7
- 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/stop.d.ts +8 -0
- package/dist/commands/stop.js +119 -0
- 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 +70 -14
- package/dist/utils/env-defaults.d.ts +2 -5
- package/dist/utils/env-defaults.js +10 -5
- package/dist/utils/inherited-trace.d.ts +24 -0
- package/dist/utils/inherited-trace.js +40 -0
- package/dist/utils/sdk-compat.d.ts +24 -0
- package/dist/utils/sdk-compat.js +120 -0
- package/package.json +13 -10
package/dist/commands/execute.js
CHANGED
|
@@ -6,40 +6,85 @@
|
|
|
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
|
-
* e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
11
11
|
* --verbose Debug output mode (default: raw agent response only)
|
|
12
12
|
* --config/-c <path> Config file path override
|
|
13
13
|
* --output-format <fmt> Output format (json|text|stream-json)
|
|
14
14
|
* --effort <level> Model effort (high|medium|low)
|
|
15
|
-
* -f/--prompt-file <path> Read task body from file
|
|
15
|
+
* -f/--prompt-file <path> Read task body from file
|
|
16
|
+
* --detach/--async Persist a receipt and launch a detached runner
|
|
17
|
+
* --wait Force synchronous execution
|
|
16
18
|
*
|
|
17
19
|
* Stdin support:
|
|
18
20
|
* Pipe or redirect content into crewx x to supply the task body via stdin.
|
|
19
|
-
* e.g. cat task.md | crewx x "@agent label"
|
|
20
21
|
* Stdin is ignored when running in an interactive TTY.
|
|
21
22
|
*/
|
|
22
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.runDetachedMiddle = void 0;
|
|
23
25
|
exports.handleExecute = handleExecute;
|
|
24
26
|
const sdk_1 = require("@crewx/sdk");
|
|
27
|
+
const repository_1 = require("@crewx/sdk/repository");
|
|
25
28
|
const parse_agent_message_1 = require("./parse-agent-message");
|
|
26
29
|
const parse_common_flags_1 = require("./parse-common-flags");
|
|
27
30
|
const resolve_prompt_1 = require("./resolve-prompt");
|
|
28
31
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
29
32
|
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
33
|
+
const write_output_1 = require("./write-output");
|
|
34
|
+
const detached_1 = require("./detached");
|
|
35
|
+
const emit_trailer_1 = require("./emit-trailer");
|
|
36
|
+
// Exported for platform-focused tests; the middle hop remains an internal CLI
|
|
37
|
+
// contract and is not routed through the public command registry.
|
|
38
|
+
var detached_2 = require("./detached");
|
|
39
|
+
Object.defineProperty(exports, "runDetachedMiddle", { enumerable: true, get: function () { return detached_2.runDetachedMiddle; } });
|
|
30
40
|
/**
|
|
31
41
|
* Handle `crewx execute <agentRef> <message>` command.
|
|
32
42
|
*
|
|
33
43
|
* Default output: raw agent response only (stdout).
|
|
34
44
|
* --verbose: debug info written to stderr, response to stdout.
|
|
35
45
|
*/
|
|
36
|
-
async function handleExecute(args) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
async function handleExecute(args, command = 'execute', emitState = (0, emit_trailer_1.createDelegationEmitState)()) {
|
|
47
|
+
// The private middle-hop marker is consumed before public flag parsing. An
|
|
48
|
+
// invalid direct use remains an unknown option and is rejected normally.
|
|
49
|
+
const middleHop = (0, detached_1.readDetachedMiddleHop)(args);
|
|
50
|
+
if (middleHop) {
|
|
51
|
+
await (0, detached_1.runDetachedMiddle)(command, middleHop);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const receiptFlags = (0, detached_1.extractReceiptFlags)(args);
|
|
55
|
+
const receiptMode = (0, detached_1.resolveReceiptMode)({
|
|
56
|
+
detach: receiptFlags.detach,
|
|
57
|
+
wait: receiptFlags.wait,
|
|
58
|
+
detachedRunner: (0, inherited_trace_1.isDetachedRunner)(),
|
|
59
|
+
agentContext: Boolean(process.env['CREWX_AGENT_ID']),
|
|
60
|
+
});
|
|
61
|
+
if (receiptMode.receipt) {
|
|
62
|
+
await (0, detached_1.runDetached)(command, receiptFlags.rest, receiptMode.reason);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let parsedFlags;
|
|
66
|
+
try {
|
|
67
|
+
parsedFlags = (0, parse_common_flags_1.parseCommonFlags)(receiptFlags.rest);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, isError: true, state: emitState });
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
const { thread, provider, model, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = parsedFlags;
|
|
74
|
+
const inheritedTrace = (0, inherited_trace_1.readInheritedTrace)();
|
|
75
|
+
let parsedAgentRef;
|
|
76
|
+
let message;
|
|
77
|
+
let finalMessage;
|
|
78
|
+
try {
|
|
79
|
+
({ agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest));
|
|
80
|
+
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
81
|
+
finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
40
87
|
const agentRef = parsedAgentRef || '@crewx';
|
|
41
|
-
// Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
|
|
42
|
-
const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
|
|
43
88
|
if (!finalMessage) {
|
|
44
89
|
console.error('Usage: crewx execute [@agent] <task> [options]');
|
|
45
90
|
console.error(' crewx x [@agent] <task> [options]');
|
|
@@ -55,6 +100,7 @@ async function handleExecute(args) {
|
|
|
55
100
|
console.error('Options:');
|
|
56
101
|
console.error(' --thread <name> Conversation thread name');
|
|
57
102
|
console.error(' --provider <cli/xxx> Provider override');
|
|
103
|
+
console.error(' --model <name> Model override (e.g. claude-sonnet-5)');
|
|
58
104
|
console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
|
|
59
105
|
console.error(' Propagated to events/hooks/tracing.');
|
|
60
106
|
console.error(' Invalid JSON aborts with exit code 2.');
|
|
@@ -62,27 +108,43 @@ async function handleExecute(args) {
|
|
|
62
108
|
console.error(' --verbose Debug output mode');
|
|
63
109
|
console.error(' --config/-c <path> Config file path');
|
|
64
110
|
console.error(' --output-format <fmt> Output format (json|text|stream-json)');
|
|
111
|
+
console.error(' --out/-o <path> Save result to file (stdout suppressed)');
|
|
65
112
|
console.error(' --effort <level> Model effort (high|medium|low)');
|
|
66
113
|
console.error(' -f/--prompt-file <path> Read task body from file');
|
|
67
114
|
console.error(' --var key=value Template variable (repeatable)');
|
|
115
|
+
console.error(' --overdrive Activate overdrive (boost) profile for this request');
|
|
116
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
68
117
|
process.exit(1);
|
|
118
|
+
return;
|
|
69
119
|
}
|
|
70
120
|
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
71
121
|
// Only show exec audit span JSON in verbose mode
|
|
72
122
|
(0, sdk_1.setAuditVerbose)(verbose);
|
|
73
|
-
|
|
123
|
+
let crewx;
|
|
124
|
+
try {
|
|
125
|
+
crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
74
131
|
// file:// remote agent delegation is handled transparently inside Crewx.query/execute.
|
|
75
132
|
if (verbose) {
|
|
133
|
+
process.stderr.write(`mode=sync reason=${receiptMode.reason}\n`);
|
|
76
134
|
process.stderr.write(`📋 Task: ${finalMessage}\n`);
|
|
77
135
|
process.stderr.write(`🤖 Agent: ${agentRef}\n`);
|
|
78
136
|
if (thread)
|
|
79
137
|
process.stderr.write(`🔗 Thread: ${thread}\n`);
|
|
80
138
|
if (provider)
|
|
81
139
|
process.stderr.write(`🔌 Provider: ${provider}\n`);
|
|
140
|
+
if (model)
|
|
141
|
+
process.stderr.write(`🧠 Model: ${model}\n`);
|
|
82
142
|
if (outputFormat)
|
|
83
143
|
process.stderr.write(`📄 Output-format: ${outputFormat}\n`);
|
|
84
144
|
if (effort)
|
|
85
145
|
process.stderr.write(`⚡ Effort: ${effort}\n`);
|
|
146
|
+
if (overdrive)
|
|
147
|
+
process.stderr.write('🚀 Overdrive: ON\n');
|
|
86
148
|
process.stderr.write('─'.repeat(60) + '\n');
|
|
87
149
|
}
|
|
88
150
|
let parsedMetadata = {};
|
|
@@ -92,21 +154,43 @@ async function handleExecute(args) {
|
|
|
92
154
|
catch (err) {
|
|
93
155
|
const msg = err instanceof Error ? err.message : String(err);
|
|
94
156
|
process.stderr.write(`Error: ${msg}\n`);
|
|
157
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
95
158
|
process.exit(2);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// Only the detached runner may adopt a pre-issued task row. Trace variables
|
|
162
|
+
// describe the caller chain and are never used as this task's identity.
|
|
163
|
+
const detachedRunner = (0, inherited_trace_1.isDetachedRunner)();
|
|
164
|
+
const assignedTaskId = (0, inherited_trace_1.readRunnerAssignment)();
|
|
165
|
+
let selfTaskId;
|
|
166
|
+
if (assignedTaskId !== undefined) {
|
|
167
|
+
const adoption = (0, detached_1.adoptAssignedTask)(new repository_1.TaskRepository(), assignedTaskId, detachedRunner);
|
|
168
|
+
if (adoption.kind === 'failed') {
|
|
169
|
+
(0, emit_trailer_1.emitDelegationResult)({ command, trace: inheritedTrace, isError: true, state: emitState });
|
|
170
|
+
process.exit(1);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (adoption.kind === 'adopted')
|
|
174
|
+
selfTaskId = adoption.taskId;
|
|
96
175
|
}
|
|
97
176
|
let exitCode = 0;
|
|
177
|
+
let result;
|
|
98
178
|
try {
|
|
99
|
-
|
|
179
|
+
result = await crewx.execute(agentRef, finalMessage, {
|
|
100
180
|
provider,
|
|
181
|
+
model,
|
|
101
182
|
effort: effort || undefined,
|
|
183
|
+
overdrive: overdrive || undefined,
|
|
102
184
|
threadId: thread,
|
|
185
|
+
taskId: selfTaskId,
|
|
103
186
|
metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
|
|
104
187
|
vars: Object.keys(vars).length > 0 ? vars : undefined,
|
|
105
|
-
trace:
|
|
188
|
+
trace: inheritedTrace,
|
|
106
189
|
});
|
|
107
190
|
if (!result.ok) {
|
|
108
191
|
const errMsg = result.error?.message ?? 'Execute failed';
|
|
109
192
|
console.error(errMsg);
|
|
193
|
+
(0, write_output_1.appendError)(out, errMsg);
|
|
110
194
|
exitCode = 1;
|
|
111
195
|
}
|
|
112
196
|
else {
|
|
@@ -119,20 +203,41 @@ async function handleExecute(args) {
|
|
|
119
203
|
process.stderr.write('\n📄 Response:\n');
|
|
120
204
|
process.stderr.write('─'.repeat(40) + '\n');
|
|
121
205
|
}
|
|
122
|
-
|
|
123
|
-
if (verbose)
|
|
206
|
+
(0, write_output_1.writeResult)(out, result.data);
|
|
207
|
+
if (verbose)
|
|
124
208
|
process.stderr.write('\n✅ Execute completed successfully\n');
|
|
125
|
-
}
|
|
126
209
|
}
|
|
127
210
|
}
|
|
128
211
|
catch (err) {
|
|
129
212
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
130
213
|
console.error(`Error: ${errMsg}`);
|
|
214
|
+
(0, write_output_1.appendError)(out, `Error: ${errMsg}`);
|
|
131
215
|
exitCode = 1;
|
|
132
216
|
}
|
|
133
217
|
finally {
|
|
134
|
-
|
|
218
|
+
try {
|
|
219
|
+
await crewx.close();
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
223
|
+
command,
|
|
224
|
+
trace: inheritedTrace,
|
|
225
|
+
taskId: result?.meta.taskId,
|
|
226
|
+
agentId: result?.meta.agentId,
|
|
227
|
+
isError: true,
|
|
228
|
+
state: emitState,
|
|
229
|
+
});
|
|
230
|
+
throw err;
|
|
231
|
+
}
|
|
135
232
|
}
|
|
233
|
+
(0, emit_trailer_1.emitDelegationResult)({
|
|
234
|
+
command,
|
|
235
|
+
trace: inheritedTrace,
|
|
236
|
+
taskId: result?.meta.taskId,
|
|
237
|
+
agentId: result?.meta.agentId,
|
|
238
|
+
isError: exitCode !== 0 || result?.ok === false,
|
|
239
|
+
state: emitState,
|
|
240
|
+
});
|
|
136
241
|
if (exitCode !== 0)
|
|
137
242
|
process.exit(exitCode);
|
|
138
243
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CREWX_HOOK_COMMAND_RE = void 0;
|
|
4
|
+
/** Match only commands that invoke CrewX's hook-dispatch subcommand. */
|
|
5
|
+
exports.CREWX_HOOK_COMMAND_RE = /crewx(?:\.js|\.cmd|\.exe)?['"]?\s+hook-dispatch\b/i;
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* - Never traverses parent directories — project root determined by crewx.yaml
|
|
11
11
|
*/
|
|
12
12
|
import { type HookProvider } from './paths';
|
|
13
|
-
export declare const CREWX_HOOK_COMMAND_MARKER = "crewx hook-dispatch";
|
|
14
13
|
export declare function resolveCrewxBinary(): string;
|
|
15
14
|
export interface HookInstallOpts {
|
|
16
15
|
projectRoot: string;
|
|
@@ -10,49 +10,14 @@
|
|
|
10
10
|
* - Preserves existing user hooks
|
|
11
11
|
* - Never traverses parent directories — project root determined by crewx.yaml
|
|
12
12
|
*/
|
|
13
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
-
}
|
|
19
|
-
Object.defineProperty(o, k2, desc);
|
|
20
|
-
}) : (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
o[k2] = m[k];
|
|
23
|
-
}));
|
|
24
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
-
}) : function(o, v) {
|
|
27
|
-
o["default"] = v;
|
|
28
|
-
});
|
|
29
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
-
var ownKeys = function(o) {
|
|
31
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
-
var ar = [];
|
|
33
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
-
return ar;
|
|
35
|
-
};
|
|
36
|
-
return ownKeys(o);
|
|
37
|
-
};
|
|
38
|
-
return function (mod) {
|
|
39
|
-
if (mod && mod.__esModule) return mod;
|
|
40
|
-
var result = {};
|
|
41
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
-
__setModuleDefault(result, mod);
|
|
43
|
-
return result;
|
|
44
|
-
};
|
|
45
|
-
})();
|
|
46
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
-
exports.CREWX_HOOK_COMMAND_MARKER = void 0;
|
|
48
14
|
exports.resolveCrewxBinary = resolveCrewxBinary;
|
|
49
15
|
exports.handleHookInstall = handleHookInstall;
|
|
50
16
|
const fs_1 = require("fs");
|
|
51
|
-
const
|
|
52
|
-
const cp = __importStar(require("child_process"));
|
|
17
|
+
const sdk_1 = require("@crewx/sdk");
|
|
53
18
|
const paths_1 = require("./paths");
|
|
54
|
-
|
|
55
|
-
function getProviderConfigs(projectRoot, providers
|
|
19
|
+
const command_marker_1 = require("./command-marker");
|
|
20
|
+
function getProviderConfigs(projectRoot, providers) {
|
|
56
21
|
return providers.map((provider) => ({
|
|
57
22
|
settingsPath: provider === 'claude'
|
|
58
23
|
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
@@ -63,24 +28,13 @@ function getProviderConfigs(projectRoot, providers, crewxBin) {
|
|
|
63
28
|
}));
|
|
64
29
|
}
|
|
65
30
|
function resolveCrewxBinary() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const which = cp.execSync('which crewx 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
70
|
-
const isTmpProxy = which.includes('/T/crewx-proxy-') ||
|
|
71
|
-
which.includes('/tmp/crewx-proxy-') ||
|
|
72
|
-
/\/[Tt]e?mp\//.test(which);
|
|
73
|
-
if (which && !isTmpProxy)
|
|
74
|
-
return which;
|
|
31
|
+
const resolution = (0, sdk_1.resolveCrewxExecutable)();
|
|
32
|
+
if (!resolution.ok) {
|
|
33
|
+
throw new Error((0, sdk_1.formatCrewxExecutableFailure)(resolution));
|
|
75
34
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if ((0, fs_1.existsSync)(scriptPath)) {
|
|
80
|
-
return `${process.execPath} ${scriptPath}`;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return 'crewx';
|
|
35
|
+
const stableEntrypoint = (0, sdk_1.materializeCrewxStableEntrypoint)(resolution);
|
|
36
|
+
const useStable = stableEntrypoint && resolution.argv.some(sdk_1.isRotatingInstallPath);
|
|
37
|
+
return (0, sdk_1.formatCrewxExecutableArgv)(useStable ? [stableEntrypoint] : resolution.argv);
|
|
84
38
|
}
|
|
85
39
|
function readSettingsTyped(settingsPath) {
|
|
86
40
|
return (0, paths_1.readSettings)(settingsPath);
|
|
@@ -88,10 +42,19 @@ function readSettingsTyped(settingsPath) {
|
|
|
88
42
|
function findCrewxEntry(preToolUse) {
|
|
89
43
|
if (!preToolUse)
|
|
90
44
|
return -1;
|
|
91
|
-
return preToolUse.findIndex((entry) => entry.hooks?.some((h) => h.command
|
|
45
|
+
return preToolUse.findIndex((entry) => entry.hooks?.some((h) => command_marker_1.CREWX_HOOK_COMMAND_RE.test(h.command)));
|
|
46
|
+
}
|
|
47
|
+
function findCrewxHook(entry) {
|
|
48
|
+
if (!entry.hooks)
|
|
49
|
+
return undefined;
|
|
50
|
+
const index = entry.hooks.findIndex((hook) => command_marker_1.CREWX_HOOK_COMMAND_RE.test(hook.command));
|
|
51
|
+
if (index < 0)
|
|
52
|
+
return undefined;
|
|
53
|
+
return { index, command: entry.hooks[index].command };
|
|
92
54
|
}
|
|
93
55
|
function installForProvider(projectRoot, config, crewxBin, yes) {
|
|
94
56
|
const { settingsPath, provider, matcher, commandArg } = config;
|
|
57
|
+
const command = `${crewxBin} hook-dispatch ${commandArg}`;
|
|
95
58
|
const settings = readSettingsTyped(settingsPath);
|
|
96
59
|
if (!settings.hooks)
|
|
97
60
|
settings.hooks = {};
|
|
@@ -99,8 +62,28 @@ function installForProvider(projectRoot, config, crewxBin, yes) {
|
|
|
99
62
|
settings.hooks.PreToolUse = [];
|
|
100
63
|
const existingIdx = findCrewxEntry(settings.hooks.PreToolUse);
|
|
101
64
|
if (existingIdx >= 0) {
|
|
102
|
-
|
|
103
|
-
|
|
65
|
+
const existingEntry = settings.hooks.PreToolUse[existingIdx];
|
|
66
|
+
const existingHook = findCrewxHook(existingEntry);
|
|
67
|
+
if (existingHook?.command === command) {
|
|
68
|
+
console.log(`[crewx] Hook already installed in ${settingsPath} (${provider})`);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (!yes) {
|
|
72
|
+
console.log(`[crewx] Existing CrewX hook needs an install-path refresh in ${settingsPath} (${provider})`);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if ((0, fs_1.existsSync)(settingsPath)) {
|
|
76
|
+
const backupPath = settingsPath + '.crewx-backup';
|
|
77
|
+
(0, fs_1.copyFileSync)(settingsPath, backupPath);
|
|
78
|
+
console.log(`[crewx] Backup created: ${backupPath}`);
|
|
79
|
+
}
|
|
80
|
+
if (existingHook) {
|
|
81
|
+
existingEntry.hooks[existingHook.index] = { ...existingEntry.hooks[existingHook.index], command };
|
|
82
|
+
}
|
|
83
|
+
(0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
|
84
|
+
console.log(`[crewx] Hook updated (${provider}): ${command}`);
|
|
85
|
+
console.log(`[crewx] Settings: ${settingsPath}`);
|
|
86
|
+
return true;
|
|
104
87
|
}
|
|
105
88
|
if (!yes) {
|
|
106
89
|
console.log(`⚠️ crewx hook install will register crewx-hook-dispatch as a PreToolUse hook.\n` +
|
|
@@ -119,7 +102,6 @@ function installForProvider(projectRoot, config, crewxBin, yes) {
|
|
|
119
102
|
else {
|
|
120
103
|
(0, paths_1.ensureCodexHooks)(projectRoot);
|
|
121
104
|
}
|
|
122
|
-
const command = `${crewxBin} hook-dispatch ${commandArg}`;
|
|
123
105
|
settings.hooks.PreToolUse.push({
|
|
124
106
|
matcher,
|
|
125
107
|
hooks: [{ type: 'command', command }],
|
|
@@ -133,8 +115,15 @@ async function handleHookInstall(argsOrOpts) {
|
|
|
133
115
|
if (!Array.isArray(argsOrOpts)) {
|
|
134
116
|
const { projectRoot, yes, provider } = argsOrOpts;
|
|
135
117
|
const providers = (0, paths_1.providersFromFilter)(provider ?? 'all');
|
|
136
|
-
|
|
137
|
-
|
|
118
|
+
let crewxBin;
|
|
119
|
+
try {
|
|
120
|
+
crewxBin = resolveCrewxBinary();
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error(`[crewx] ${error instanceof Error ? error.message : String(error)}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const configs = getProviderConfigs(projectRoot, providers);
|
|
138
127
|
for (const config of configs) {
|
|
139
128
|
installForProvider(projectRoot, config, crewxBin, yes);
|
|
140
129
|
}
|
|
@@ -152,8 +141,16 @@ async function handleHookInstall(argsOrOpts) {
|
|
|
152
141
|
}
|
|
153
142
|
const providerFilter = (0, paths_1.parseProviderArg)(args);
|
|
154
143
|
const providers = (0, paths_1.providersFromFilter)(providerFilter);
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
let crewxBin;
|
|
145
|
+
try {
|
|
146
|
+
crewxBin = resolveCrewxBinary();
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
console.error(`[crewx] ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
+
process.exitCode = 1;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const configs = getProviderConfigs(projectRoot, providers);
|
|
157
154
|
if (!yes) {
|
|
158
155
|
const targets = configs.map((c) => ` - ${c.provider}: ${c.settingsPath}`).join('\n');
|
|
159
156
|
console.log(`⚠️ crewx hook install will register crewx-hook-dispatch as a PreToolUse hook.\n` +
|
|
@@ -11,7 +11,7 @@ const fs_1 = require("fs");
|
|
|
11
11
|
const path_1 = require("path");
|
|
12
12
|
const sdk_1 = require("@crewx/sdk");
|
|
13
13
|
const paths_1 = require("./paths");
|
|
14
|
-
const
|
|
14
|
+
const command_marker_1 = require("./command-marker");
|
|
15
15
|
function showProviderStatus(projectRoot, provider) {
|
|
16
16
|
const settingsPath = provider === 'claude'
|
|
17
17
|
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
@@ -26,9 +26,9 @@ function showProviderStatus(projectRoot, provider) {
|
|
|
26
26
|
try {
|
|
27
27
|
const settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf8'));
|
|
28
28
|
const preHooks = settings.hooks?.PreToolUse ?? [];
|
|
29
|
-
const crewxEntry = preHooks.find((entry) => entry.hooks?.some((h) => h.command
|
|
29
|
+
const crewxEntry = preHooks.find((entry) => entry.hooks?.some((h) => command_marker_1.CREWX_HOOK_COMMAND_RE.test(h.command ?? '')));
|
|
30
30
|
if (crewxEntry) {
|
|
31
|
-
const command = crewxEntry.hooks.find((h) => h.command
|
|
31
|
+
const command = crewxEntry.hooks.find((h) => command_marker_1.CREWX_HOOK_COMMAND_RE.test(h.command ?? ''))?.command;
|
|
32
32
|
console.log(` Status: INSTALLED`);
|
|
33
33
|
console.log(` Command: ${command}`);
|
|
34
34
|
}
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.handleHookUninstall = handleHookUninstall;
|
|
11
11
|
const fs_1 = require("fs");
|
|
12
12
|
const paths_1 = require("./paths");
|
|
13
|
-
const
|
|
13
|
+
const command_marker_1 = require("./command-marker");
|
|
14
14
|
function getSettingsPath(projectRoot, provider) {
|
|
15
15
|
return provider === 'claude'
|
|
16
16
|
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
@@ -35,7 +35,7 @@ function uninstallFromProvider(projectRoot, provider) {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
const before = settings.hooks.PreToolUse.length;
|
|
38
|
-
settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter((entry) => !entry.hooks?.some((h) => h.command
|
|
38
|
+
settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter((entry) => !entry.hooks?.some((h) => command_marker_1.CREWX_HOOK_COMMAND_RE.test(h.command)));
|
|
39
39
|
const removed = settings.hooks.PreToolUse.length < before;
|
|
40
40
|
if (settings.hooks.PreToolUse.length === 0) {
|
|
41
41
|
delete settings.hooks.PreToolUse;
|
package/dist/commands/init.js
CHANGED
|
@@ -52,6 +52,7 @@ const git = __importStar(require("isomorphic-git"));
|
|
|
52
52
|
const nodeFs = __importStar(require("fs"));
|
|
53
53
|
const os_1 = __importDefault(require("os"));
|
|
54
54
|
const repository_1 = require("@crewx/sdk/repository");
|
|
55
|
+
const sdk_1 = require("@crewx/sdk");
|
|
55
56
|
const install_1 = require("./hook/install");
|
|
56
57
|
const STATUSLINE_SCRIPT_NAME = 'claude-usage-statusline.js';
|
|
57
58
|
const STATUSLINE_SCRIPT_MARKER = 'CrewX claude-usage-statusline';
|
|
@@ -84,6 +85,11 @@ const CREWX_MARKER = '# CrewX runtime';
|
|
|
84
85
|
const CREWX_GITIGNORE = `# CrewX runtime
|
|
85
86
|
.crewx/
|
|
86
87
|
|
|
88
|
+
# Secrets (workspace .env — see docs/manual)
|
|
89
|
+
.env
|
|
90
|
+
.env.*
|
|
91
|
+
!.env.example
|
|
92
|
+
|
|
87
93
|
# Memory runtime state (regenerable from entries/)
|
|
88
94
|
memory/*/.dirty-summary
|
|
89
95
|
memory/*/graph.json
|
|
@@ -435,7 +441,7 @@ async function handleInit(opts) {
|
|
|
435
441
|
}
|
|
436
442
|
}
|
|
437
443
|
// Always create docs dirs and templates, regardless of whether yaml was skipped
|
|
438
|
-
for (const dir of ['.crewx/logs', '.claude/commands', 'docs/goal', 'docs/daily', 'docs/wi']) {
|
|
444
|
+
for (const dir of ['.crewx/logs', '.claude/commands', 'docs/goal', 'docs/daily', 'docs/wi', 'workflows']) {
|
|
439
445
|
try {
|
|
440
446
|
(0, fs_1.mkdirSync)((0, path_1.join)(target, dir), { recursive: true });
|
|
441
447
|
}
|
|
@@ -456,6 +462,21 @@ async function handleInit(opts) {
|
|
|
456
462
|
console.log(`✅ ${t.dir}/ ${action} (${t.file})`);
|
|
457
463
|
}
|
|
458
464
|
}
|
|
465
|
+
try {
|
|
466
|
+
const workflowTemplatesDir = (0, sdk_1.resolveWorkflowTemplatesPath)();
|
|
467
|
+
for (const filename of [sdk_1.WI_DEFAULT_FLOW_FILENAME, sdk_1.WI_PLAN_FLOW_FILENAME]) {
|
|
468
|
+
const sourcePath = (0, path_1.join)(workflowTemplatesDir, filename);
|
|
469
|
+
const targetPath = (0, path_1.join)(target, 'workflows', filename);
|
|
470
|
+
if (force || !(0, fs_1.existsSync)(targetPath)) {
|
|
471
|
+
const action = (0, fs_1.existsSync)(targetPath) ? 'updated' : 'created';
|
|
472
|
+
(0, fs_1.copyFileSync)(sourcePath, targetPath);
|
|
473
|
+
console.log(`✅ workflows/ ${action} (${filename})`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
catch (e) {
|
|
478
|
+
errors.push(`WORKFLOW_TEMPLATE_FAILED:${e.message}`);
|
|
479
|
+
}
|
|
459
480
|
// Always register workspace in ~/.crewx/crewx.db (best-effort, idempotent)
|
|
460
481
|
let workspaceId;
|
|
461
482
|
let slug;
|
package/dist/commands/kill.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* Kills a running task by ID or kills all running tasks.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* crewx kill <task-id> Kill a specific running task
|
|
7
|
-
* crewx kill --all Kill all running tasks
|
|
8
|
-
*/
|
|
1
|
+
/** Compatibility entry point for `crewx kill`; the implementation lives in stop.ts. */
|
|
2
|
+
export { handleStop } from './stop';
|
|
9
3
|
export declare function handleKill(args: string[]): Promise<void>;
|
package/dist/commands/kill.js
CHANGED
|
@@ -1,52 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* crewx kill handler.
|
|
4
|
-
* Kills a running task by ID or kills all running tasks.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* crewx kill <task-id> Kill a specific running task
|
|
8
|
-
* crewx kill --all Kill all running tasks
|
|
9
|
-
*/
|
|
10
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleStop = void 0;
|
|
11
4
|
exports.handleKill = handleKill;
|
|
12
|
-
|
|
5
|
+
/** Compatibility entry point for `crewx kill`; the implementation lives in stop.ts. */
|
|
6
|
+
var stop_1 = require("./stop");
|
|
7
|
+
Object.defineProperty(exports, "handleStop", { enumerable: true, get: function () { return stop_1.handleStop; } });
|
|
8
|
+
const stop_2 = require("./stop");
|
|
13
9
|
async function handleKill(args) {
|
|
14
|
-
|
|
15
|
-
const taskId = args.find(a => !a.startsWith('--'));
|
|
16
|
-
if (!taskId && !killAll) {
|
|
17
|
-
console.error('Error: Please provide a task ID or use --all to kill all running tasks.');
|
|
18
|
-
console.error('');
|
|
19
|
-
console.error('Usage:');
|
|
20
|
-
console.error(' crewx kill <task-id> Kill a running task by ID');
|
|
21
|
-
console.error(' crewx kill --all Kill all running tasks');
|
|
22
|
-
process.exit(1);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const repo = new repository_1.TaskRepository();
|
|
26
|
-
if (killAll) {
|
|
27
|
-
const running = repo.getRunningTasks();
|
|
28
|
-
if (running.length === 0) {
|
|
29
|
-
console.log('No running tasks found.');
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
console.log(`Found ${running.length} running task(s). Killing...`);
|
|
33
|
-
for (const task of running) {
|
|
34
|
-
const r = repo.killTask(task.id);
|
|
35
|
-
if (r.killed) {
|
|
36
|
-
console.log(`Killed task ${task.id}${r.pid ? ` (PID: ${r.pid})` : ''}`);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
console.log(`Task ${task.id} could not be killed (may have already finished)`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const r = repo.killTask(taskId);
|
|
45
|
-
if (r.killed) {
|
|
46
|
-
console.log(`Killed task ${taskId}${r.pid ? ` (PID: ${r.pid})` : ''}`);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
console.error(`Error: Task not found or not running: ${taskId}`);
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
10
|
+
return (0, stop_2.handleStop)(args, 'kill');
|
|
52
11
|
}
|
package/dist/commands/log.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.handleLog = handleLog;
|
|
13
|
+
const sdk_1 = require("@crewx/sdk");
|
|
13
14
|
const repository_1 = require("@crewx/sdk/repository");
|
|
14
15
|
function statusIcon(status) {
|
|
15
16
|
switch (status) {
|
|
@@ -36,10 +37,10 @@ async function handleLog(args) {
|
|
|
36
37
|
console.log(`Status: ${statusIcon(task.status)} ${task.status}`);
|
|
37
38
|
console.log(`Agent: ${task.agent_id ?? '—'}`);
|
|
38
39
|
console.log(`Mode: ${task.mode ?? '—'}`);
|
|
39
|
-
console.log(`Started: ${new Date(task.started_at)
|
|
40
|
+
console.log(`Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
|
|
40
41
|
if (task.completed_at) {
|
|
41
42
|
const duration = new Date(task.completed_at).getTime() - new Date(task.started_at).getTime();
|
|
42
|
-
console.log(`Completed: ${new Date(task.completed_at)
|
|
43
|
+
console.log(`Completed: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.completed_at))} (${duration}ms)`);
|
|
43
44
|
}
|
|
44
45
|
console.log('='.repeat(60));
|
|
45
46
|
console.log('');
|
|
@@ -78,7 +79,7 @@ async function handleLog(args) {
|
|
|
78
79
|
: 'running...';
|
|
79
80
|
console.log(`${idx + 1}. ${icon} ${task.id}`);
|
|
80
81
|
console.log(` Agent: ${task.agent_id ?? '—'} Mode: ${task.mode ?? '—'}`);
|
|
81
|
-
console.log(` Started: ${new Date(task.started_at)
|
|
82
|
+
console.log(` Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
|
|
82
83
|
console.log(` Duration: ${duration}`);
|
|
83
84
|
console.log('');
|
|
84
85
|
});
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Common flag parser for query/execute commands.
|
|
3
3
|
*
|
|
4
4
|
* Supports both `--flag=value` and `--flag value` forms.
|
|
5
|
-
* Handles: --thread, --provider, --metadata, --verbose, --config/-c,
|
|
6
|
-
* --output-format, --effort, --prompt-file/-f.
|
|
5
|
+
* Handles: --thread, --provider, --model, --metadata, --verbose, --config/-c,
|
|
6
|
+
* --output-format, --effort, --prompt-file/-f, --overdrive.
|
|
7
7
|
*
|
|
8
8
|
* Strict mode: unknown --xxx tokens after known flags are consumed throw an
|
|
9
9
|
* error instead of silently leaking into the message prompt.
|
|
@@ -14,6 +14,8 @@ export interface CommonFlags {
|
|
|
14
14
|
thread?: string;
|
|
15
15
|
/** Provider override (e.g., cli/claude). */
|
|
16
16
|
provider?: string;
|
|
17
|
+
/** Model override (e.g., claude-sonnet-5). */
|
|
18
|
+
model?: string;
|
|
17
19
|
/** Raw metadata JSON string. */
|
|
18
20
|
metadata?: string;
|
|
19
21
|
/** Enable verbose/debug output mode. */
|
|
@@ -26,6 +28,10 @@ export interface CommonFlags {
|
|
|
26
28
|
effort?: string;
|
|
27
29
|
/** Path to a file whose content is used as the prompt body (-f/--prompt-file). */
|
|
28
30
|
promptFile?: string;
|
|
31
|
+
/** Whether overdrive (boost) is active for this request. */
|
|
32
|
+
overdrive: boolean;
|
|
33
|
+
/** Output file path for saving result (--out/-o). */
|
|
34
|
+
out?: string;
|
|
29
35
|
/** Template variables from --var key=value flags. */
|
|
30
36
|
vars: Record<string, string>;
|
|
31
37
|
/** Remaining non-flag positional arguments. */
|