@crewx/cli 0.9.0-rc.9 → 0.9.0-rc.90
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 +13 -0
- package/dist/bootstrap/codex-writable-roots.js +25 -0
- package/dist/bootstrap/crewx-cli.js +2 -1
- package/dist/builtin.js +1 -0
- package/dist/commands/agent.js +0 -58
- package/dist/commands/db.d.ts +1 -0
- package/dist/commands/db.js +191 -1
- 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 +6 -1
- package/dist/commands/execute.js +162 -11
- 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/log.js +4 -3
- package/dist/commands/parse-common-flags.d.ts +5 -1
- package/dist/commands/parse-common-flags.js +6 -2
- package/dist/commands/ps.js +7 -6
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.js +290 -0
- package/dist/commands/query.d.ts +3 -1
- package/dist/commands/query.js +78 -11
- package/dist/commands/registry.js +3 -1
- package/dist/commands/result.d.ts +7 -3
- package/dist/commands/result.js +41 -6
- package/dist/commands/shortcut.d.ts +1 -0
- package/dist/commands/shortcut.js +267 -0
- package/dist/commands/slack.js +2 -1
- package/dist/commands/write-output.d.ts +3 -0
- package/dist/commands/write-output.js +24 -0
- package/dist/logging.d.ts +1 -1
- package/dist/logging.js +3 -2
- package/dist/main.d.ts +3 -2
- package/dist/main.js +56 -11
- package/dist/utils/env-defaults.d.ts +2 -5
- package/dist/utils/env-defaults.js +10 -5
- package/dist/utils/sdk-compat.d.ts +24 -0
- package/dist/utils/sdk-compat.js +120 -0
- package/package.json +13 -11
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleShortcut = handleShortcut;
|
|
4
|
+
/**
|
|
5
|
+
* crewx shortcut handler — thin CLI wrapper over @crewx/sdk/desktop.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* crewx shortcut status [--json]
|
|
9
|
+
* crewx shortcut install [--force] [--json]
|
|
10
|
+
* crewx shortcut uninstall [--json]
|
|
11
|
+
*
|
|
12
|
+
* All win32/foreign/superseded/force judgment lives in @crewx/sdk/desktop.
|
|
13
|
+
* This module only parses argv, forwards options, and renders the result.
|
|
14
|
+
*/
|
|
15
|
+
const desktop_1 = require("@crewx/sdk/desktop");
|
|
16
|
+
const parse_common_flags_1 = require("./parse-common-flags");
|
|
17
|
+
const NOT_WINDOWS_MESSAGE = 'NOT_WINDOWS: Desktop shortcuts are only supported on Windows.';
|
|
18
|
+
function parseShortcutFlags(args, allowForce) {
|
|
19
|
+
let json = false;
|
|
20
|
+
let force = false;
|
|
21
|
+
for (const arg of args) {
|
|
22
|
+
if (arg === '--json') {
|
|
23
|
+
json = true;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (arg === '--force' && allowForce) {
|
|
27
|
+
force = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
throw new parse_common_flags_1.UnknownOptionError(`Unknown option: ${arg}`);
|
|
31
|
+
}
|
|
32
|
+
return { json, force };
|
|
33
|
+
}
|
|
34
|
+
/** Forwarded verbatim to stderr as each SDK phase starts — never buffered. */
|
|
35
|
+
function onProgress(event) {
|
|
36
|
+
process.stderr.write(`[shortcut] ${event.message}\n`);
|
|
37
|
+
}
|
|
38
|
+
function printJson(payload) {
|
|
39
|
+
console.log(JSON.stringify(payload));
|
|
40
|
+
}
|
|
41
|
+
/** Prints the error and exits 1. Never returns (matches `process.exit`'s `never` type). */
|
|
42
|
+
function failWithError(err, json) {
|
|
43
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
44
|
+
if (json) {
|
|
45
|
+
printJson({ success: false, error: message });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error(`✗ ${message}`);
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
/** The SDK returns `supported:false` (no throw) for install/uninstall on non-Windows. */
|
|
53
|
+
function failNotWindows(json) {
|
|
54
|
+
if (json) {
|
|
55
|
+
printJson({ success: false, supported: false, state: 'unsupported', error: NOT_WINDOWS_MESSAGE });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.error(`✗ ${NOT_WINDOWS_MESSAGE}`);
|
|
59
|
+
}
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Detects the two ways a resolved (non-thrown) install result must NOT be
|
|
64
|
+
* read as success: a `superseded` shortcut (checked via both `state` and the
|
|
65
|
+
* `errors[]` entry, since either alone could otherwise be missed) and an
|
|
66
|
+
* unconfirmed global install (`installedGlobal:false` with
|
|
67
|
+
* `GLOBAL_INSTALL_UNCONFIRMED` in errors — npm exited 0 but re-detection
|
|
68
|
+
* could not confirm it).
|
|
69
|
+
*/
|
|
70
|
+
function installFailureReason(result) {
|
|
71
|
+
const supersededError = result.errors.find((e) => e.startsWith('SUPERSEDED:'));
|
|
72
|
+
if (result.state === 'superseded' || supersededError) {
|
|
73
|
+
return supersededError ?? 'Installed shortcut belongs to a newer CrewX version; refusing to modify it.';
|
|
74
|
+
}
|
|
75
|
+
const unconfirmedError = result.errors.find((e) => e.startsWith('GLOBAL_INSTALL_UNCONFIRMED:'));
|
|
76
|
+
if (!result.installedGlobal && unconfirmedError) {
|
|
77
|
+
return unconfirmedError;
|
|
78
|
+
}
|
|
79
|
+
if (result.errors.length > 0) {
|
|
80
|
+
return result.errors[0];
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Only these two re-detected states mean the Desktop truly has no CrewX
|
|
86
|
+
* shortcut left. Everything else — `foreign`/`superseded` (SDK refused to
|
|
87
|
+
* touch it) and `installed`/`stale` (the `.lnk` unlink threw and was
|
|
88
|
+
* swallowed as "already gone" — install.ts `uninstallShortcut`) — means the
|
|
89
|
+
* file is still on disk. A success ALLOWLIST is used instead of enumerating
|
|
90
|
+
* failure states so an unlink failure (EPERM/EBUSY/locked/AV hook) that
|
|
91
|
+
* re-detects back to `installed` fails closed by construction, rather than
|
|
92
|
+
* requiring every new failure path to be added to an exclusion list.
|
|
93
|
+
*/
|
|
94
|
+
const UNINSTALL_SUCCESS_STATES = new Set(['declined', 'not-installed']);
|
|
95
|
+
function uninstallFailureReason(result) {
|
|
96
|
+
if (UNINSTALL_SUCCESS_STATES.has(result.state)) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const supersededError = result.errors.find((e) => e.startsWith('SUPERSEDED:'));
|
|
100
|
+
if (result.state === 'superseded' || supersededError) {
|
|
101
|
+
return supersededError ?? 'Installed shortcut belongs to a newer CrewX version; nothing was removed.';
|
|
102
|
+
}
|
|
103
|
+
if (result.state === 'foreign') {
|
|
104
|
+
const nsisError = result.errors.find((e) => e.startsWith('NSIS_PRESENT:'));
|
|
105
|
+
return nsisError ?? 'Existing Desktop shortcut is not managed by CrewX; nothing was removed.';
|
|
106
|
+
}
|
|
107
|
+
if (result.errors.length > 0) {
|
|
108
|
+
return result.errors[0];
|
|
109
|
+
}
|
|
110
|
+
return `CrewX desktop shortcut could not be removed (state: ${result.state}).`;
|
|
111
|
+
}
|
|
112
|
+
function printStatusHuman(status) {
|
|
113
|
+
switch (status.state) {
|
|
114
|
+
case 'unsupported':
|
|
115
|
+
console.log('Desktop shortcuts are only supported on Windows.');
|
|
116
|
+
break;
|
|
117
|
+
case 'not-installed':
|
|
118
|
+
console.log('No CrewX desktop shortcut installed yet.');
|
|
119
|
+
console.log('Run `crewx shortcut install` to create one.');
|
|
120
|
+
break;
|
|
121
|
+
case 'declined':
|
|
122
|
+
console.log('CrewX desktop shortcut setup was previously dismissed.');
|
|
123
|
+
console.log('Run `crewx shortcut install` to create one.');
|
|
124
|
+
break;
|
|
125
|
+
case 'installed':
|
|
126
|
+
console.log('✓ CrewX desktop shortcut is installed and up to date.');
|
|
127
|
+
if (status.shortcutPath)
|
|
128
|
+
console.log(` Shortcut: ${status.shortcutPath}`);
|
|
129
|
+
break;
|
|
130
|
+
case 'stale':
|
|
131
|
+
console.log('⚠ CrewX desktop shortcut needs an update.');
|
|
132
|
+
console.log('Run `crewx shortcut install` to refresh it.');
|
|
133
|
+
break;
|
|
134
|
+
case 'foreign':
|
|
135
|
+
console.log('⚠ A Desktop shortcut exists that CrewX does not manage.');
|
|
136
|
+
console.log('Run `crewx shortcut install --force` to replace it.');
|
|
137
|
+
break;
|
|
138
|
+
case 'superseded':
|
|
139
|
+
console.log('⚠ The installed shortcut belongs to a newer CrewX version than the one running.');
|
|
140
|
+
console.log('Update CrewX before touching the shortcut.');
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
for (const e of status.errors) {
|
|
144
|
+
console.log(` note: ${e}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function runStatus(args) {
|
|
148
|
+
const { json } = parseShortcutFlags(args, false);
|
|
149
|
+
let status;
|
|
150
|
+
try {
|
|
151
|
+
status = await (0, desktop_1.getShortcutStatus)();
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
failWithError(err, json);
|
|
155
|
+
}
|
|
156
|
+
if (json) {
|
|
157
|
+
printJson(status);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
printStatusHuman(status);
|
|
161
|
+
}
|
|
162
|
+
async function runInstall(args) {
|
|
163
|
+
const { json, force } = parseShortcutFlags(args, true);
|
|
164
|
+
let result;
|
|
165
|
+
try {
|
|
166
|
+
result = await (0, desktop_1.installShortcut)({ force, onProgress });
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
failWithError(err, json);
|
|
170
|
+
}
|
|
171
|
+
if (!result.supported) {
|
|
172
|
+
failNotWindows(json);
|
|
173
|
+
}
|
|
174
|
+
const failure = installFailureReason(result);
|
|
175
|
+
if (failure) {
|
|
176
|
+
if (json) {
|
|
177
|
+
printJson({ ...result, success: false });
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
console.error(`✗ ${failure}`);
|
|
181
|
+
}
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
if (json) {
|
|
185
|
+
printJson({ ...result, success: true });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (result.changed) {
|
|
189
|
+
console.log('✓ CrewX desktop shortcut installed. Double-click "CrewX" on your Desktop to launch it.');
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log('✓ CrewX desktop shortcut is already up to date. Double-click "CrewX" on your Desktop to launch it.');
|
|
193
|
+
}
|
|
194
|
+
if (result.shortcutPath)
|
|
195
|
+
console.log(` Shortcut: ${result.shortcutPath}`);
|
|
196
|
+
}
|
|
197
|
+
async function runUninstall(args) {
|
|
198
|
+
const { json } = parseShortcutFlags(args, false);
|
|
199
|
+
let result;
|
|
200
|
+
try {
|
|
201
|
+
result = await (0, desktop_1.uninstallShortcut)();
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
failWithError(err, json);
|
|
205
|
+
}
|
|
206
|
+
if (!result.supported) {
|
|
207
|
+
failNotWindows(json);
|
|
208
|
+
}
|
|
209
|
+
const failure = uninstallFailureReason(result);
|
|
210
|
+
if (failure) {
|
|
211
|
+
if (json) {
|
|
212
|
+
printJson({ ...result, success: false });
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
console.error(`✗ ${failure}`);
|
|
216
|
+
for (const e of result.errors) {
|
|
217
|
+
if (e !== failure)
|
|
218
|
+
console.error(` note: ${e}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
if (json) {
|
|
224
|
+
printJson({ ...result, success: true });
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
console.log('✓ CrewX desktop shortcut removed.');
|
|
228
|
+
}
|
|
229
|
+
function printHelp() {
|
|
230
|
+
console.log(`
|
|
231
|
+
crewx shortcut — manage the Windows Desktop shortcut for CrewX
|
|
232
|
+
|
|
233
|
+
Usage:
|
|
234
|
+
crewx shortcut status [--json]
|
|
235
|
+
crewx shortcut install [--force] [--json]
|
|
236
|
+
crewx shortcut uninstall [--json]
|
|
237
|
+
|
|
238
|
+
Options:
|
|
239
|
+
--json Print machine-readable JSON to stdout (progress/log always go to stderr)
|
|
240
|
+
--force (install only) Overwrite a Desktop shortcut CrewX does not manage.
|
|
241
|
+
Never overwrites a shortcut created by a newer CrewX version.
|
|
242
|
+
|
|
243
|
+
Notes:
|
|
244
|
+
Windows only. On macOS/Linux, \`status\` reports state "unsupported" (exit 0);
|
|
245
|
+
\`install\`/\`uninstall\` exit 1 with no changes made.
|
|
246
|
+
`.trim());
|
|
247
|
+
}
|
|
248
|
+
async function handleShortcut(args) {
|
|
249
|
+
const subcommand = args[0];
|
|
250
|
+
if (!subcommand || subcommand === 'help' || subcommand === '--help' || subcommand === '-h') {
|
|
251
|
+
printHelp();
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const rest = args.slice(1);
|
|
255
|
+
switch (subcommand) {
|
|
256
|
+
case 'status':
|
|
257
|
+
return runStatus(rest);
|
|
258
|
+
case 'install':
|
|
259
|
+
return runInstall(rest);
|
|
260
|
+
case 'uninstall':
|
|
261
|
+
return runUninstall(rest);
|
|
262
|
+
default:
|
|
263
|
+
console.error(`Unknown shortcut subcommand: ${subcommand}`);
|
|
264
|
+
console.error('Run `crewx shortcut help` for usage.');
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
}
|
package/dist/commands/slack.js
CHANGED
|
@@ -44,6 +44,7 @@ exports.handleSlack = handleSlack;
|
|
|
44
44
|
const fs = __importStar(require("fs"));
|
|
45
45
|
const path = __importStar(require("path"));
|
|
46
46
|
const https = __importStar(require("https"));
|
|
47
|
+
const sdk_1 = require("@crewx/sdk");
|
|
47
48
|
const adapter_slack_1 = require("@crewx/adapter-slack");
|
|
48
49
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
49
50
|
const markdown_1 = require("../slack/markdown");
|
|
@@ -186,7 +187,7 @@ async function handleListFiles(threadId) {
|
|
|
186
187
|
console.log(` 📎 ${file.fileName}`);
|
|
187
188
|
console.log(` Size: ${formatFileSize(file.fileSize)}`);
|
|
188
189
|
console.log(` Path: ${file.filePath}`);
|
|
189
|
-
console.log(` Downloaded: ${file.downloadedAt
|
|
190
|
+
console.log(` Downloaded: ${(0, sdk_1.formatDisplayTimestamp)(file.downloadedAt)}`);
|
|
190
191
|
console.log('');
|
|
191
192
|
}
|
|
192
193
|
console.log(`Total: ${files.length} file${files.length > 1 ? 's' : ''}\n`);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeResult = writeResult;
|
|
4
|
+
exports.appendError = appendError;
|
|
5
|
+
/**
|
|
6
|
+
* EPIPE-safe result output.
|
|
7
|
+
* - out specified: write success result to file (sync, no stream EPIPE)
|
|
8
|
+
* - out not specified: fall back to existing stdout (console.log)
|
|
9
|
+
*/
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
function writeResult(out, data) {
|
|
12
|
+
if (out) {
|
|
13
|
+
(0, fs_1.writeFileSync)(out, data, 'utf8');
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.log(data);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** On failure: if out is specified, append to file (avoid empty file). stderr is kept by the caller. */
|
|
20
|
+
function appendError(out, message) {
|
|
21
|
+
if (out) {
|
|
22
|
+
(0, fs_1.appendFileSync)(out, message.endsWith('\n') ? message : message + '\n', 'utf8');
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/logging.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Format mirrors cli-bak TaskManagementService for backward compatibility.
|
|
11
11
|
*/
|
|
12
|
-
import type
|
|
12
|
+
import { type Crewx } from '@crewx/sdk';
|
|
13
13
|
/**
|
|
14
14
|
* Attach file-based logging to a Crewx instance.
|
|
15
15
|
* Subscribes to task:start and task:end events and writes log files.
|
package/dist/logging.js
CHANGED
|
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.attachFileLogger = attachFileLogger;
|
|
15
15
|
const fs_1 = require("fs");
|
|
16
16
|
const path_1 = require("path");
|
|
17
|
+
const sdk_1 = require("@crewx/sdk");
|
|
17
18
|
const CREWX_VERSION = '0.9.0-alpha.1';
|
|
18
19
|
/** Format Date as YYYYMMDDTHHmmss (local time) */
|
|
19
20
|
function formatTimestamp(date) {
|
|
@@ -52,7 +53,7 @@ function attachFileLogger(crewx, workspaceRoot) {
|
|
|
52
53
|
`CrewX Version: ${CREWX_VERSION}\n` +
|
|
53
54
|
`Mode: ${event.mode}\n` +
|
|
54
55
|
`Agent: ${event.agentRef}\n` +
|
|
55
|
-
`Started: ${event.timestamp
|
|
56
|
+
`Started: ${(0, sdk_1.formatDisplayTimestamp)(event.timestamp)}\n` +
|
|
56
57
|
`Message: ${event.message}\n` +
|
|
57
58
|
`\n`;
|
|
58
59
|
(0, fs_1.writeFileSync)(logFile, header, { encoding: 'utf8', mode: 0o600 });
|
|
@@ -66,7 +67,7 @@ function attachFileLogger(crewx, workspaceRoot) {
|
|
|
66
67
|
const logFile = logFiles.get(event.traceId);
|
|
67
68
|
if (!logFile)
|
|
68
69
|
return;
|
|
69
|
-
const ts = new Date()
|
|
70
|
+
const ts = (0, sdk_1.formatDisplayTimestamp)(new Date());
|
|
70
71
|
const status = event.error
|
|
71
72
|
? `failed: ${event.error.message}`
|
|
72
73
|
: 'completed successfully';
|
package/dist/main.d.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Boot sequence:
|
|
7
7
|
* 1. Inject CREWX_CLI / CREWX_WORKSPACE env defaults (must be first)
|
|
8
|
-
* 2.
|
|
9
|
-
* 3.
|
|
8
|
+
* 2. Load workspace .env (does not override existing process.env values)
|
|
9
|
+
* 3. Parse command
|
|
10
|
+
* 4. Dispatch to handler
|
|
10
11
|
*/
|
|
11
12
|
export {};
|
package/dist/main.js
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Boot sequence:
|
|
8
8
|
* 1. Inject CREWX_CLI / CREWX_WORKSPACE env defaults (must be first)
|
|
9
|
-
* 2.
|
|
10
|
-
* 3.
|
|
9
|
+
* 2. Load workspace .env (does not override existing process.env values)
|
|
10
|
+
* 3. Parse command
|
|
11
|
+
* 4. Dispatch to handler
|
|
11
12
|
*/
|
|
12
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
14
|
if (k2 === undefined) k2 = k;
|
|
@@ -45,15 +46,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
45
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
47
|
// ─── P0-1: Env Bootstrap ─────────────────────────────────────────────────────
|
|
47
48
|
// Must run before any other code that might use process.env.CREWX_CLI.
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
process.env.
|
|
49
|
+
const sdk_compat_1 = require("./utils/sdk-compat");
|
|
50
|
+
const dotenv = __importStar(require("dotenv"));
|
|
51
|
+
const path_1 = require("path");
|
|
52
|
+
process.env.CREWX_CLI ??= sdk_compat_1.sdkCompat.resolveCrewxCli();
|
|
53
|
+
process.env.CREWX_WORKSPACE ??= sdk_compat_1.sdkCompat.resolveCrewxWorkspace();
|
|
54
|
+
// Load the workspace .env (WI-20260725-010): keeps CLI (crewx q/x) in parity with
|
|
55
|
+
// the server's ConfigModule, which already reads cwd/.env. override:false so a
|
|
56
|
+
// value already present in the shell/environment always wins over the file.
|
|
57
|
+
// quiet:true suppresses dotenv's injected-keys log and tip banner on stdout.
|
|
58
|
+
dotenv.config({ path: (0, path_1.join)(process.env.CREWX_WORKSPACE, '.env'), override: false, quiet: true });
|
|
52
59
|
// ─── Pricing remote override (WI-20260701-002) ───────────────────────────────
|
|
53
60
|
// Best-effort, non-blocking: fetch remote model registry so new models get
|
|
54
61
|
// accurate pricing without a CLI republish. Falls back to bundled table on
|
|
55
62
|
// failure / offline. Browser entry does not call this automatically.
|
|
56
|
-
|
|
63
|
+
sdk_compat_1.sdkCompat.initPricingRemote();
|
|
57
64
|
// ─── Command Imports ──────────────────────────────────────────────────────────
|
|
58
65
|
const query_1 = require("./commands/query");
|
|
59
66
|
const execute_1 = require("./commands/execute");
|
|
@@ -65,6 +72,8 @@ const restart_1 = require("./commands/restart");
|
|
|
65
72
|
const log_1 = require("./commands/log");
|
|
66
73
|
const doctor_1 = require("./commands/doctor");
|
|
67
74
|
const init_1 = require("./commands/init");
|
|
75
|
+
const shortcut_1 = require("./commands/shortcut");
|
|
76
|
+
const publish_1 = require("./commands/publish");
|
|
68
77
|
const builtin_1 = require("./builtin");
|
|
69
78
|
const slack_1 = require("./commands/slack");
|
|
70
79
|
const install_1 = require("./commands/hook/install");
|
|
@@ -75,6 +84,7 @@ const db_1 = require("./commands/db");
|
|
|
75
84
|
const parse_common_flags_1 = require("./commands/parse-common-flags");
|
|
76
85
|
const registry_1 = require("./commands/registry");
|
|
77
86
|
const version_1 = require("./utils/version");
|
|
87
|
+
const emit_trailer_1 = require("./commands/emit-trailer");
|
|
78
88
|
/**
|
|
79
89
|
* Dev-only SSOT assertion: bin/cli-commands.js must be the exact union of
|
|
80
90
|
* KNOWN_COMMANDS ∪ BUILTIN_COMMAND_NAMES ∪ NOT_YET_MIGRATED from registry.ts.
|
|
@@ -99,7 +109,7 @@ async function assertSsotParity() {
|
|
|
99
109
|
(extra.length ? ` CLI_SUBCOMMANDS has, registry missing: ${extra.join(', ')}` : ''));
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
async function main() {
|
|
112
|
+
async function main(emitState) {
|
|
103
113
|
if (process.env['NODE_ENV'] === 'development') {
|
|
104
114
|
await assertSsotParity();
|
|
105
115
|
}
|
|
@@ -119,11 +129,11 @@ async function main() {
|
|
|
119
129
|
// P0-2: q/x aliases
|
|
120
130
|
case 'q':
|
|
121
131
|
case 'query':
|
|
122
|
-
await (0, query_1.handleQuery)(args.slice(1));
|
|
132
|
+
await (0, query_1.handleQuery)(args.slice(1), command, emitState);
|
|
123
133
|
return;
|
|
124
134
|
case 'x':
|
|
125
135
|
case 'execute':
|
|
126
|
-
await (0, execute_1.handleExecute)(args.slice(1));
|
|
136
|
+
await (0, execute_1.handleExecute)(args.slice(1), command, emitState);
|
|
127
137
|
return;
|
|
128
138
|
case 'agent':
|
|
129
139
|
await (0, agent_1.handleAgent)(args.slice(1));
|
|
@@ -181,6 +191,14 @@ async function main() {
|
|
|
181
191
|
case 'db':
|
|
182
192
|
await (0, db_1.handleDb)(args.slice(1));
|
|
183
193
|
return;
|
|
194
|
+
// Windows Desktop shortcut: crewx shortcut status|install|uninstall
|
|
195
|
+
case 'shortcut':
|
|
196
|
+
await (0, shortcut_1.handleShortcut)(args.slice(1));
|
|
197
|
+
return;
|
|
198
|
+
// crewx publish [dir] [--dry-run] [--version <semver>] [--json] [--upload]
|
|
199
|
+
case 'publish':
|
|
200
|
+
await (0, publish_1.handlePublish)(args.slice(1));
|
|
201
|
+
return;
|
|
184
202
|
// SDK-009: slack / slack:files
|
|
185
203
|
case 'slack':
|
|
186
204
|
case 'slack:files':
|
|
@@ -262,12 +280,19 @@ Query / Execute:
|
|
|
262
280
|
--verbose Debug output mode (default: raw response only)
|
|
263
281
|
--config/-c <path> Config file path (default: CREWX_CONFIG or crewx.yaml)
|
|
264
282
|
--output-format <fmt> Output format (json|text|stream-json)
|
|
283
|
+
--out/-o <path> Save result to file (stdout suppressed)
|
|
265
284
|
--effort <level> Model effort (high|medium|low)
|
|
266
285
|
-f/--prompt-file <path> Read task body from file (bypasses argv length limits)
|
|
267
286
|
--var key=value Template variable (repeatable). Accessible as {{key}} in agent prompt.
|
|
268
287
|
-- End of flags; remaining tokens treated as message text
|
|
269
288
|
e.g. crewx q "@agent label" -- --flag-in-message
|
|
270
289
|
|
|
290
|
+
x/execute only:
|
|
291
|
+
--detach Re-spawn as a detached background runner; print task-id
|
|
292
|
+
and exit 0 immediately. Ignored if CREWX_TRACE_ID is
|
|
293
|
+
already set (recursive-spawn guard). Unsupported on win32.
|
|
294
|
+
e.g. crewx x "@agent label" --detach
|
|
295
|
+
|
|
271
296
|
Agent Management:
|
|
272
297
|
agent ls [options] List configured agents
|
|
273
298
|
--role <value> Filter by role (comma-separated for OR match)
|
|
@@ -280,6 +305,8 @@ Task Management:
|
|
|
280
305
|
kill <task-id> Kill a running task
|
|
281
306
|
kill --all Kill all running tasks
|
|
282
307
|
result [task-id] Get task result (or list recent tasks)
|
|
308
|
+
--wait=N Poll (1s interval) up to N seconds for the task to
|
|
309
|
+
finish. Exit 124 on timeout. --wait=0 = single check.
|
|
283
310
|
restart <task-id> Restart a failed task as a new task
|
|
284
311
|
|
|
285
312
|
Logs & Diagnostics:
|
|
@@ -291,6 +318,22 @@ Database:
|
|
|
291
318
|
db push Sync DB schema to current code (additive only)
|
|
292
319
|
--force Reset migration history + skip confirmation
|
|
293
320
|
--dry-run Preview changes without applying
|
|
321
|
+
db migrate-task-logs Backfill legacy tasks.logs into task_log_events
|
|
322
|
+
--dry-run Validate and estimate without writing
|
|
323
|
+
--apply Consistent backup + resumable task-by-task apply
|
|
324
|
+
--verify Check event/source invariants and parity
|
|
325
|
+
|
|
326
|
+
Desktop Shortcut (Windows only):
|
|
327
|
+
shortcut status [--json] Show current shortcut status
|
|
328
|
+
shortcut install [--force] [--json] Install/repair the Desktop shortcut
|
|
329
|
+
shortcut uninstall [--json] Remove the Desktop shortcut
|
|
330
|
+
|
|
331
|
+
Publish:
|
|
332
|
+
publish [dir] [options] Package a workspace as a distributable template archive
|
|
333
|
+
--dry-run Scan + build manifest only; do not write a .tgz
|
|
334
|
+
--version <ver> Override manifest version (semver)
|
|
335
|
+
--json Print machine-readable JSON to stdout
|
|
336
|
+
--upload Submit + upload using the SDK account session
|
|
294
337
|
|
|
295
338
|
Built-in Tools:
|
|
296
339
|
memory <args> Memory tool
|
|
@@ -312,7 +355,9 @@ Global Options:
|
|
|
312
355
|
--version, -v Show version
|
|
313
356
|
`.trim());
|
|
314
357
|
}
|
|
315
|
-
|
|
358
|
+
const emitState = (0, emit_trailer_1.createDelegationEmitState)();
|
|
359
|
+
main(emitState).catch((err) => {
|
|
316
360
|
console.error(err instanceof Error ? err.message : String(err));
|
|
361
|
+
(0, emit_trailer_1.emitDelegationResult)({ command: process.argv[2], isError: true, state: emitState });
|
|
317
362
|
process.exit(err instanceof parse_common_flags_1.UnknownOptionError ? 2 : 1);
|
|
318
363
|
});
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Re-exported from @crewx/sdk for convenience.
|
|
4
|
-
*/
|
|
5
|
-
export { resolveCrewxCli, resolveCrewxWorkspace } from '@crewx/sdk';
|
|
1
|
+
export declare function resolveCrewxCli(): string;
|
|
2
|
+
export declare function resolveCrewxWorkspace(): string;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.resolveCrewxCli = resolveCrewxCli;
|
|
4
|
+
exports.resolveCrewxWorkspace = resolveCrewxWorkspace;
|
|
4
5
|
/**
|
|
5
6
|
* CREWX_* environment variable defaults for CLI bootstrap.
|
|
6
|
-
*
|
|
7
|
+
* Routed through the SDK compatibility accessor for older SDK installations.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const sdk_compat_1 = require("./sdk-compat");
|
|
10
|
+
function resolveCrewxCli() {
|
|
11
|
+
return sdk_compat_1.sdkCompat.resolveCrewxCli();
|
|
12
|
+
}
|
|
13
|
+
function resolveCrewxWorkspace() {
|
|
14
|
+
return sdk_compat_1.sdkCompat.resolveCrewxWorkspace();
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CrewxExecutableResolution } from '@crewx/sdk';
|
|
2
|
+
type PricingInitializer = () => Promise<unknown> | unknown;
|
|
3
|
+
export interface SdkLike {
|
|
4
|
+
resolveCrewxCli?: () => string;
|
|
5
|
+
resolveCrewxCliArgv?: () => CrewxExecutableResolution;
|
|
6
|
+
resolveCrewxWorkspace?: () => string;
|
|
7
|
+
initPricingRemote?: PricingInitializer;
|
|
8
|
+
}
|
|
9
|
+
export interface SdkCompat {
|
|
10
|
+
resolveCrewxCli(): string;
|
|
11
|
+
resolveCrewxCliArgv(): CrewxExecutableResolution;
|
|
12
|
+
resolveCrewxWorkspace(): string;
|
|
13
|
+
initPricingRemote(): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create the CLI bootstrap capability accessor for the installed SDK.
|
|
17
|
+
*
|
|
18
|
+
* SDK exports are additive across compatible majors, so an older SDK may not
|
|
19
|
+
* expose every capability that a newer CLI knows about. Optional capabilities
|
|
20
|
+
* are checked here rather than at each bootstrap call site.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSdkCompat(sdkLike?: SdkLike): SdkCompat;
|
|
23
|
+
export declare const sdkCompat: SdkCompat;
|
|
24
|
+
export {};
|