@crewx/cli 0.9.0-rc.8 ā 0.9.0-rc.80
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 +17 -0
- package/dist/commands/doctor.js +21 -11
- package/dist/commands/execute.d.ts +4 -0
- package/dist/commands/execute.js +103 -3
- 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 +270 -0
- package/dist/commands/query.d.ts +1 -0
- package/dist/commands/query.js +11 -2
- 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 +49 -7
- package/dist/utils/env-defaults.d.ts +2 -5
- package/dist/utils/env-defaults.js +10 -5
- package/dist/utils/sdk-compat.d.ts +21 -0
- package/dist/utils/sdk-compat.js +72 -0
- package/package.json +13 -11
package/dist/commands/query.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Flags:
|
|
7
7
|
* --thread <name> Conversation thread name
|
|
8
8
|
* --provider <cli/xxx> Provider override
|
|
9
|
+
* --model <name> Model override (e.g. claude-sonnet-5)
|
|
9
10
|
* --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
|
|
10
11
|
* e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
11
12
|
* --verbose Debug output mode (default: raw agent response only)
|
|
@@ -27,6 +28,7 @@ const parse_common_flags_1 = require("./parse-common-flags");
|
|
|
27
28
|
const resolve_prompt_1 = require("./resolve-prompt");
|
|
28
29
|
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
29
30
|
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
31
|
+
const write_output_1 = require("./write-output");
|
|
30
32
|
/**
|
|
31
33
|
* Handle `crewx query <agentRef> <message>` command.
|
|
32
34
|
*
|
|
@@ -34,7 +36,7 @@ const inherited_trace_1 = require("../utils/inherited-trace");
|
|
|
34
36
|
* --verbose: debug info written to stderr, response to stdout.
|
|
35
37
|
*/
|
|
36
38
|
async function handleQuery(args) {
|
|
37
|
-
const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
39
|
+
const { thread, provider, model, metadata, verbose, config, outputFormat, effort, promptFile, overdrive, vars, out, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
38
40
|
const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
|
|
39
41
|
// No @mention ā default to @crewx agent (matches cli-bak behaviour)
|
|
40
42
|
const agentRef = parsedAgentRef || '@crewx';
|
|
@@ -55,6 +57,7 @@ async function handleQuery(args) {
|
|
|
55
57
|
console.error('Options:');
|
|
56
58
|
console.error(' --thread <name> Conversation thread name');
|
|
57
59
|
console.error(' --provider <cli/xxx> Provider override');
|
|
60
|
+
console.error(' --model <name> Model override (e.g. claude-sonnet-5)');
|
|
58
61
|
console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
|
|
59
62
|
console.error(' Propagated to events/hooks/tracing.');
|
|
60
63
|
console.error(' Invalid JSON aborts with exit code 2.');
|
|
@@ -62,6 +65,7 @@ async function handleQuery(args) {
|
|
|
62
65
|
console.error(' --verbose Debug output mode');
|
|
63
66
|
console.error(' --config/-c <path> Config file path');
|
|
64
67
|
console.error(' --output-format <fmt> Output format (json|text|stream-json)');
|
|
68
|
+
console.error(' --out/-o <path> Save result to file (stdout suppressed)');
|
|
65
69
|
console.error(' --effort <level> Model effort (high|medium|low)');
|
|
66
70
|
console.error(' -f/--prompt-file <path> Read prompt body from file');
|
|
67
71
|
console.error(' --var key=value Template variable (repeatable)');
|
|
@@ -80,6 +84,8 @@ async function handleQuery(args) {
|
|
|
80
84
|
process.stderr.write(`š Thread: ${thread}\n`);
|
|
81
85
|
if (provider)
|
|
82
86
|
process.stderr.write(`š Provider: ${provider}\n`);
|
|
87
|
+
if (model)
|
|
88
|
+
process.stderr.write(`š§ Model: ${model}\n`);
|
|
83
89
|
if (outputFormat)
|
|
84
90
|
process.stderr.write(`š Output-format: ${outputFormat}\n`);
|
|
85
91
|
if (effort)
|
|
@@ -101,6 +107,7 @@ async function handleQuery(args) {
|
|
|
101
107
|
try {
|
|
102
108
|
const result = await crewx.query(agentRef, finalMessage, {
|
|
103
109
|
provider,
|
|
110
|
+
model,
|
|
104
111
|
effort: effort || undefined,
|
|
105
112
|
overdrive: overdrive || undefined,
|
|
106
113
|
threadId: thread,
|
|
@@ -111,6 +118,7 @@ async function handleQuery(args) {
|
|
|
111
118
|
if (!result.ok) {
|
|
112
119
|
const errMsg = result.error?.message ?? 'Query failed';
|
|
113
120
|
console.error(errMsg);
|
|
121
|
+
(0, write_output_1.appendError)(out, errMsg);
|
|
114
122
|
exitCode = 1;
|
|
115
123
|
}
|
|
116
124
|
else {
|
|
@@ -123,7 +131,7 @@ async function handleQuery(args) {
|
|
|
123
131
|
process.stderr.write('\nš Response:\n');
|
|
124
132
|
process.stderr.write('ā'.repeat(40) + '\n');
|
|
125
133
|
}
|
|
126
|
-
|
|
134
|
+
(0, write_output_1.writeResult)(out, result.data);
|
|
127
135
|
if (verbose) {
|
|
128
136
|
process.stderr.write('\nā
Query completed successfully\n');
|
|
129
137
|
}
|
|
@@ -132,6 +140,7 @@ async function handleQuery(args) {
|
|
|
132
140
|
catch (err) {
|
|
133
141
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
134
142
|
console.error(`Error: ${errMsg}`);
|
|
143
|
+
(0, write_output_1.appendError)(out, `Error: ${errMsg}`);
|
|
135
144
|
exitCode = 1;
|
|
136
145
|
}
|
|
137
146
|
finally {
|
|
@@ -17,13 +17,15 @@ exports.KNOWN_COMMANDS = new Set([
|
|
|
17
17
|
'doctor', 'init',
|
|
18
18
|
'db',
|
|
19
19
|
'help',
|
|
20
|
+
'shortcut',
|
|
21
|
+
'publish',
|
|
20
22
|
'slack', 'slack:files',
|
|
21
23
|
'hook', 'hook-dispatch',
|
|
22
24
|
]);
|
|
23
25
|
/** Built-in tool commands routed via handleBuiltin(). */
|
|
24
26
|
exports.BUILTIN_COMMAND_NAMES = new Set([
|
|
25
27
|
'memory', 'search', 'doc', 'wbs', 'cron', 'workflow', 'skill', 'dreaming',
|
|
26
|
-
'wi', 'chromex',
|
|
28
|
+
'wi', 'chromex', 'notify',
|
|
27
29
|
]);
|
|
28
30
|
/** Commands not yet migrated from cli-bak ā show a migration message. */
|
|
29
31
|
exports.NOT_YET_MIGRATED = new Set([
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
* Retrieves the result of a completed task by its ID.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* crewx result <task-id>
|
|
7
|
-
* crewx result <task-id> --json
|
|
8
|
-
* crewx result
|
|
6
|
+
* crewx result <task-id> Print raw result
|
|
7
|
+
* crewx result <task-id> --json Print full task record as JSON
|
|
8
|
+
* crewx result <task-id> --wait=N Poll (1s interval) up to N seconds for
|
|
9
|
+
* the task to leave 'running'. Exit 124 on
|
|
10
|
+
* timeout. --wait=0 behaves like no --wait
|
|
11
|
+
* (single immediate check).
|
|
12
|
+
* crewx result List recent tasks (latest 10)
|
|
9
13
|
*/
|
|
10
14
|
export declare function handleResult(args: string[]): Promise<void>;
|
package/dist/commands/result.js
CHANGED
|
@@ -4,13 +4,19 @@
|
|
|
4
4
|
* Retrieves the result of a completed task by its ID.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* crewx result <task-id>
|
|
8
|
-
* crewx result <task-id> --json
|
|
9
|
-
* crewx result
|
|
7
|
+
* crewx result <task-id> Print raw result
|
|
8
|
+
* crewx result <task-id> --json Print full task record as JSON
|
|
9
|
+
* crewx result <task-id> --wait=N Poll (1s interval) up to N seconds for
|
|
10
|
+
* the task to leave 'running'. Exit 124 on
|
|
11
|
+
* timeout. --wait=0 behaves like no --wait
|
|
12
|
+
* (single immediate check).
|
|
13
|
+
* crewx result List recent tasks (latest 10)
|
|
10
14
|
*/
|
|
11
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
16
|
exports.handleResult = handleResult;
|
|
17
|
+
const sdk_1 = require("@crewx/sdk");
|
|
13
18
|
const repository_1 = require("@crewx/sdk/repository");
|
|
19
|
+
const POLL_INTERVAL_MS = 1000;
|
|
14
20
|
function statusIcon(status) {
|
|
15
21
|
switch (status) {
|
|
16
22
|
case 'running': return 'ā³';
|
|
@@ -19,8 +25,20 @@ function statusIcon(status) {
|
|
|
19
25
|
default: return 'ā';
|
|
20
26
|
}
|
|
21
27
|
}
|
|
28
|
+
function sleep(ms) {
|
|
29
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
30
|
+
}
|
|
31
|
+
/** Parses `--wait=N` (seconds). Returns undefined when the flag is absent. */
|
|
32
|
+
function parseWaitSeconds(args) {
|
|
33
|
+
const arg = args.find(a => a.startsWith('--wait='));
|
|
34
|
+
if (arg === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
const n = Number(arg.slice('--wait='.length));
|
|
37
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
38
|
+
}
|
|
22
39
|
async function handleResult(args) {
|
|
23
40
|
const jsonMode = args.includes('--json');
|
|
41
|
+
const waitSeconds = parseWaitSeconds(args);
|
|
24
42
|
const taskId = args.find(a => !a.startsWith('--'));
|
|
25
43
|
const repo = new repository_1.TaskRepository();
|
|
26
44
|
if (!taskId) {
|
|
@@ -36,21 +54,38 @@ async function handleResult(args) {
|
|
|
36
54
|
const icon = statusIcon(task.status);
|
|
37
55
|
console.log(`${idx + 1}. ${icon} ${task.id}`);
|
|
38
56
|
console.log(` Agent: ${task.agent_id ?? 'ā'} Mode: ${task.mode ?? 'ā'}`);
|
|
39
|
-
console.log(` Started: ${new Date(task.started_at)
|
|
57
|
+
console.log(` Started: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.started_at))}`);
|
|
40
58
|
if (task.completed_at) {
|
|
41
|
-
console.log(` Completed: ${new Date(task.completed_at)
|
|
59
|
+
console.log(` Completed: ${(0, sdk_1.formatDisplayTimestamp)(new Date(task.completed_at))}`);
|
|
42
60
|
}
|
|
43
61
|
console.log('');
|
|
44
62
|
});
|
|
45
63
|
console.log('Tip: Run `crewx result <task-id>` to see full output.');
|
|
46
64
|
return;
|
|
47
65
|
}
|
|
48
|
-
|
|
66
|
+
let task = repo.getTask(taskId);
|
|
49
67
|
if (!task) {
|
|
50
68
|
console.error(`Error: Task not found: ${taskId}`);
|
|
51
69
|
process.exit(1);
|
|
52
70
|
return;
|
|
53
71
|
}
|
|
72
|
+
if (waitSeconds !== undefined && waitSeconds > 0 && task.status === 'running') {
|
|
73
|
+
const deadline = Date.now() + waitSeconds * 1000;
|
|
74
|
+
while (task && task.status === 'running') {
|
|
75
|
+
if (Date.now() >= deadline) {
|
|
76
|
+
console.error(`Task ${taskId} did not complete within --wait=${waitSeconds}s (status: running).`);
|
|
77
|
+
process.exit(124);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await sleep(Math.min(POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())));
|
|
81
|
+
task = repo.getTask(taskId);
|
|
82
|
+
if (!task) {
|
|
83
|
+
console.error(`Error: Task not found: ${taskId}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
54
89
|
if (jsonMode) {
|
|
55
90
|
console.log(JSON.stringify(task, null, 2));
|
|
56
91
|
return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleShortcut(args: string[]): Promise<void>;
|
|
@@ -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 {};
|