@crewx/cli 0.8.0-rc.66 → 0.8.0-rc.82
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/bin/crewx +2 -0
- package/dist/bootstrap/crewx-cli.d.ts +11 -0
- package/dist/bootstrap/crewx-cli.js +31 -0
- package/dist/builtin.d.ts +15 -0
- package/dist/{cli/builtin.handler.js → builtin.js} +21 -7
- package/dist/commands/agent.d.ts +12 -0
- package/dist/commands/agent.js +246 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.js +190 -0
- package/dist/commands/execute.d.ts +21 -0
- package/dist/commands/execute.js +117 -0
- package/dist/commands/hook/install.d.ts +21 -0
- package/dist/commands/hook/install.js +175 -0
- package/dist/commands/hook/paths.d.ts +19 -0
- package/dist/commands/hook/paths.js +94 -0
- package/dist/commands/hook/status.d.ts +7 -0
- package/dist/commands/hook/status.js +86 -0
- package/dist/commands/hook/uninstall.d.ts +8 -0
- package/dist/commands/hook/uninstall.js +71 -0
- package/dist/commands/hook-dispatch.d.ts +15 -0
- package/dist/commands/hook-dispatch.js +180 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.js +133 -0
- package/dist/commands/kill.d.ts +12 -0
- package/dist/commands/kill.js +49 -0
- package/dist/commands/log.d.ts +13 -0
- package/dist/commands/log.js +97 -0
- package/dist/commands/parse-agent-message.d.ts +31 -0
- package/dist/commands/parse-agent-message.js +52 -0
- package/dist/commands/parse-common-flags.d.ts +36 -0
- package/dist/commands/parse-common-flags.js +105 -0
- package/dist/commands/ps.d.ts +12 -0
- package/dist/commands/ps.js +71 -0
- package/dist/commands/query.d.ts +21 -0
- package/dist/commands/query.js +117 -0
- package/dist/commands/result.d.ts +13 -0
- package/dist/commands/result.js +73 -0
- package/dist/commands/slack.d.ts +12 -0
- package/dist/commands/slack.js +559 -0
- package/dist/commands/task-db.d.ts +33 -0
- package/dist/commands/task-db.js +107 -0
- package/dist/examples/deny-secrets-plugin.d.ts +22 -0
- package/dist/examples/deny-secrets-plugin.js +40 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/logging.d.ts +21 -0
- package/dist/logging.js +86 -0
- package/dist/main.d.ts +10 -0
- package/dist/main.js +246 -256
- package/dist/plugins/examples/echo-hook.d.ts +24 -0
- package/dist/plugins/examples/echo-hook.js +60 -0
- package/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
- package/dist/plugins/examples/verify-echo-hook.js +47 -0
- package/dist/plugins/sqlite-tracing.d.ts +13 -0
- package/dist/plugins/sqlite-tracing.js +20 -0
- package/dist/register-builtin-tools.d.ts +5 -0
- package/dist/register-builtin-tools.js +9 -0
- package/dist/slack/file-download.d.ts +17 -0
- package/dist/slack/file-download.js +134 -0
- package/dist/slack/markdown.d.ts +5 -0
- package/dist/slack/markdown.js +33 -0
- package/dist/utils/env-defaults.d.ts +5 -0
- package/dist/utils/env-defaults.js +10 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.js +28 -0
- package/package.json +32 -115
- package/README.md +0 -663
- package/dist/ai-provider.service.d.ts +0 -36
- package/dist/ai-provider.service.js +0 -315
- package/dist/ai-provider.service.js.map +0 -1
- package/dist/ai.service.d.ts +0 -17
- package/dist/ai.service.js +0 -51
- package/dist/ai.service.js.map +0 -1
- package/dist/app.module.d.ts +0 -5
- package/dist/app.module.js +0 -165
- package/dist/app.module.js.map +0 -1
- package/dist/cli/agent.handler.d.ts +0 -2
- package/dist/cli/agent.handler.js +0 -186
- package/dist/cli/agent.handler.js.map +0 -1
- package/dist/cli/builtin.handler.d.ts +0 -3
- package/dist/cli/builtin.handler.js.map +0 -1
- package/dist/cli/chat.handler.d.ts +0 -20
- package/dist/cli/chat.handler.js +0 -446
- package/dist/cli/chat.handler.js.map +0 -1
- package/dist/cli/cli.handler.d.ts +0 -4
- package/dist/cli/cli.handler.js +0 -119
- package/dist/cli/cli.handler.js.map +0 -1
- package/dist/cli/doctor.handler.d.ts +0 -38
- package/dist/cli/doctor.handler.js +0 -495
- package/dist/cli/doctor.handler.js.map +0 -1
- package/dist/cli/execute.handler.d.ts +0 -2
- package/dist/cli/execute.handler.js +0 -376
- package/dist/cli/execute.handler.js.map +0 -1
- package/dist/cli/help.handler.d.ts +0 -2
- package/dist/cli/help.handler.js +0 -10
- package/dist/cli/help.handler.js.map +0 -1
- package/dist/cli/init.handler.d.ts +0 -26
- package/dist/cli/init.handler.js +0 -450
- package/dist/cli/init.handler.js.map +0 -1
- package/dist/cli/log.handler.d.ts +0 -2
- package/dist/cli/log.handler.js +0 -69
- package/dist/cli/log.handler.js.map +0 -1
- package/dist/cli/mcp.handler.d.ts +0 -3
- package/dist/cli/mcp.handler.js +0 -121
- package/dist/cli/mcp.handler.js.map +0 -1
- package/dist/cli/query.handler.d.ts +0 -2
- package/dist/cli/query.handler.js +0 -392
- package/dist/cli/query.handler.js.map +0 -1
- package/dist/cli/skill.handler.d.ts +0 -2
- package/dist/cli/skill.handler.js +0 -252
- package/dist/cli/skill.handler.js.map +0 -1
- package/dist/cli/slack-files.handler.d.ts +0 -2
- package/dist/cli/slack-files.handler.js +0 -291
- package/dist/cli/slack-files.handler.js.map +0 -1
- package/dist/cli/template.handler.d.ts +0 -2
- package/dist/cli/template.handler.js +0 -188
- package/dist/cli/template.handler.js.map +0 -1
- package/dist/cli/templates.handler.d.ts +0 -2
- package/dist/cli/templates.handler.js +0 -100
- package/dist/cli/templates.handler.js.map +0 -1
- package/dist/cli-options.d.ts +0 -40
- package/dist/cli-options.js +0 -371
- package/dist/cli-options.js.map +0 -1
- package/dist/config/timeout.config.d.ts +0 -14
- package/dist/config/timeout.config.js +0 -34
- package/dist/config/timeout.config.js.map +0 -1
- package/dist/conversation/base-conversation-history.provider.d.ts +0 -12
- package/dist/conversation/base-conversation-history.provider.js +0 -45
- package/dist/conversation/base-conversation-history.provider.js.map +0 -1
- package/dist/conversation/cli-box-reader.adapter.d.ts +0 -6
- package/dist/conversation/cli-box-reader.adapter.js +0 -10
- package/dist/conversation/cli-box-reader.adapter.js.map +0 -1
- package/dist/conversation/cli-conversation-history.provider.d.ts +0 -16
- package/dist/conversation/cli-conversation-history.provider.js +0 -112
- package/dist/conversation/cli-conversation-history.provider.js.map +0 -1
- package/dist/conversation/cli-task-reader.adapter.d.ts +0 -6
- package/dist/conversation/cli-task-reader.adapter.js +0 -25
- package/dist/conversation/cli-task-reader.adapter.js.map +0 -1
- package/dist/conversation/conversation-provider.factory.d.ts +0 -10
- package/dist/conversation/conversation-provider.factory.js +0 -50
- package/dist/conversation/conversation-provider.factory.js.map +0 -1
- package/dist/conversation/index.d.ts +0 -8
- package/dist/conversation/index.js +0 -29
- package/dist/conversation/index.js.map +0 -1
- package/dist/conversation/slack-conversation-history.provider.d.ts +0 -29
- package/dist/conversation/slack-conversation-history.provider.js +0 -302
- package/dist/conversation/slack-conversation-history.provider.js.map +0 -1
- package/dist/crewx.tool.d.ts +0 -360
- package/dist/crewx.tool.js +0 -2531
- package/dist/crewx.tool.js.map +0 -1
- package/dist/crewx.tool.spec.d.ts +0 -1
- package/dist/crewx.tool.spec.js +0 -222
- package/dist/crewx.tool.spec.js.map +0 -1
- package/dist/guards/bearer-auth.guard.d.ts +0 -7
- package/dist/guards/bearer-auth.guard.js +0 -44
- package/dist/guards/bearer-auth.guard.js.map +0 -1
- package/dist/health.controller.d.ts +0 -6
- package/dist/health.controller.js +0 -32
- package/dist/health.controller.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/mcp.controller.d.ts +0 -8
- package/dist/mcp.controller.js +0 -62
- package/dist/mcp.controller.js.map +0 -1
- package/dist/package.json +0 -3
- package/dist/providers/dynamic-provider.factory.d.ts +0 -17
- package/dist/providers/dynamic-provider.factory.js +0 -138
- package/dist/providers/dynamic-provider.factory.js.map +0 -1
- package/dist/providers/logger.adapter.d.ts +0 -7
- package/dist/providers/logger.adapter.js +0 -107
- package/dist/providers/logger.adapter.js.map +0 -1
- package/dist/services/agent-loader.service.d.ts +0 -35
- package/dist/services/agent-loader.service.js +0 -623
- package/dist/services/agent-loader.service.js.map +0 -1
- package/dist/services/auth.service.d.ts +0 -9
- package/dist/services/auth.service.js +0 -47
- package/dist/services/auth.service.js.map +0 -1
- package/dist/services/config-validator.service.d.ts +0 -29
- package/dist/services/config-validator.service.js +0 -483
- package/dist/services/config-validator.service.js.map +0 -1
- package/dist/services/config.service.d.ts +0 -45
- package/dist/services/config.service.js +0 -352
- package/dist/services/config.service.js.map +0 -1
- package/dist/services/document-loader.service.d.ts +0 -26
- package/dist/services/document-loader.service.js +0 -186
- package/dist/services/document-loader.service.js.map +0 -1
- package/dist/services/help.service.d.ts +0 -5
- package/dist/services/help.service.js +0 -139
- package/dist/services/help.service.js.map +0 -1
- package/dist/services/intelligent-compression.service.d.ts +0 -20
- package/dist/services/intelligent-compression.service.js +0 -179
- package/dist/services/intelligent-compression.service.js.map +0 -1
- package/dist/services/mcp-client.service.d.ts +0 -26
- package/dist/services/mcp-client.service.js +0 -81
- package/dist/services/mcp-client.service.js.map +0 -1
- package/dist/services/parallel-processing.service.d.ts +0 -108
- package/dist/services/parallel-processing.service.js +0 -333
- package/dist/services/parallel-processing.service.js.map +0 -1
- package/dist/services/provider-bridge.service.d.ts +0 -35
- package/dist/services/provider-bridge.service.js +0 -224
- package/dist/services/provider-bridge.service.js.map +0 -1
- package/dist/services/remote-agent.service.d.ts +0 -50
- package/dist/services/remote-agent.service.js +0 -171
- package/dist/services/remote-agent.service.js.map +0 -1
- package/dist/services/result-formatter.service.d.ts +0 -27
- package/dist/services/result-formatter.service.js +0 -126
- package/dist/services/result-formatter.service.js.map +0 -1
- package/dist/services/skill-loader.service.d.ts +0 -15
- package/dist/services/skill-loader.service.js +0 -278
- package/dist/services/skill-loader.service.js.map +0 -1
- package/dist/services/skill.service.d.ts +0 -69
- package/dist/services/skill.service.js +0 -779
- package/dist/services/skill.service.js.map +0 -1
- package/dist/services/skill.service.spec.d.ts +0 -1
- package/dist/services/skill.service.spec.js +0 -168
- package/dist/services/skill.service.spec.js.map +0 -1
- package/dist/services/task-management.service.d.ts +0 -71
- package/dist/services/task-management.service.js +0 -324
- package/dist/services/task-management.service.js.map +0 -1
- package/dist/services/template.service.d.ts +0 -61
- package/dist/services/template.service.js +0 -416
- package/dist/services/template.service.js.map +0 -1
- package/dist/services/tool-call.service.d.ts +0 -16
- package/dist/services/tool-call.service.js +0 -302
- package/dist/services/tool-call.service.js.map +0 -1
- package/dist/services/tracing.service.d.ts +0 -197
- package/dist/services/tracing.service.js +0 -1267
- package/dist/services/tracing.service.js.map +0 -1
- package/dist/slack/formatters/message.formatter.d.ts +0 -43
- package/dist/slack/formatters/message.formatter.js +0 -505
- package/dist/slack/formatters/message.formatter.js.map +0 -1
- package/dist/slack/services/slack-file-download.service.d.ts +0 -58
- package/dist/slack/services/slack-file-download.service.js +0 -558
- package/dist/slack/services/slack-file-download.service.js.map +0 -1
- package/dist/slack/slack-bot.d.ts +0 -33
- package/dist/slack/slack-bot.js +0 -568
- package/dist/slack/slack-bot.js.map +0 -1
- package/dist/stderr.logger.d.ts +0 -8
- package/dist/stderr.logger.js +0 -26
- package/dist/stderr.logger.js.map +0 -1
- package/dist/types/usage.types.d.ts +0 -107
- package/dist/types/usage.types.js +0 -3
- package/dist/types/usage.types.js.map +0 -1
- package/dist/utils/config-utils.d.ts +0 -15
- package/dist/utils/config-utils.js +0 -69
- package/dist/utils/config-utils.js.map +0 -1
- package/dist/utils/extract-text.d.ts +0 -1
- package/dist/utils/extract-text.js +0 -15
- package/dist/utils/extract-text.js.map +0 -1
- package/dist/utils/mcp-installer.d.ts +0 -20
- package/dist/utils/mcp-installer.js +0 -199
- package/dist/utils/mcp-installer.js.map +0 -1
- package/dist/utils/project-hash.d.ts +0 -6
- package/dist/utils/project-hash.js +0 -70
- package/dist/utils/project-hash.js.map +0 -1
- package/dist/utils/simple-security.d.ts +0 -3
- package/dist/utils/simple-security.js +0 -20
- package/dist/utils/simple-security.js.map +0 -1
- package/dist/utils/stdin-utils.d.ts +0 -6
- package/dist/utils/stdin-utils.js +0 -109
- package/dist/utils/stdin-utils.js.map +0 -1
- package/dist/utils/template-processor.d.ts +0 -27
- package/dist/utils/template-processor.js +0 -395
- package/dist/utils/template-processor.js.map +0 -1
- package/dist/utils/terminal-message-formatter.d.ts +0 -23
- package/dist/utils/terminal-message-formatter.js +0 -136
- package/dist/utils/terminal-message-formatter.js.map +0 -1
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -17
- package/dist/version.js.map +0 -1
- package/dist/workspace.service.d.ts +0 -44
- package/dist/workspace.service.js +0 -299
- package/dist/workspace.service.js.map +0 -1
- package/scripts/backfill-tokens.js +0 -218
- package/scripts/postbuild-cli.mjs +0 -88
- package/scripts/postinstall-cli.mjs +0 -30
- package/templates/agents/default.yaml +0 -490
- package/templates/agents/minimal.yaml +0 -16
- package/templates/documents/conversation-history-default.hbs +0 -17
- package/templates/documents/crewx-manual.md +0 -2278
- package/templates/documents/crewx-quick-guide.md +0 -147
- package/templates/versions.json +0 -19
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx hook-dispatch — CLI subcommand invoked by Claude/Codex PreToolUse hook.
|
|
4
|
+
*
|
|
5
|
+
* Reads stdin JSON from the provider, loads HookPlugins from crewx.yaml,
|
|
6
|
+
* evaluates them, and writes stdout JSON response back.
|
|
7
|
+
*
|
|
8
|
+
* Protocol:
|
|
9
|
+
* stdin → ClaudeHookInput JSON
|
|
10
|
+
* stdout → ClaudeHookOutput JSON
|
|
11
|
+
* exit 0 → allow, exit 2 → deny
|
|
12
|
+
*
|
|
13
|
+
* Security (M1):
|
|
14
|
+
* --provider argument is REQUIRED. Missing → process.exit(1) fail-closed.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.handleHookDispatch = handleHookDispatch;
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const sdk_1 = require("@crewx/sdk");
|
|
21
|
+
const hooks_1 = require("@crewx/sdk/hooks");
|
|
22
|
+
function readStdin() {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
let data = '';
|
|
25
|
+
process.stdin.setEncoding('utf8');
|
|
26
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
27
|
+
process.stdin.on('end', () => resolve(data));
|
|
28
|
+
process.stdin.on('error', reject);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function loadPlugin(pluginPath) {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
33
|
+
const mod = require(pluginPath);
|
|
34
|
+
const PluginClass = mod.default ?? mod;
|
|
35
|
+
if (typeof PluginClass !== 'function') {
|
|
36
|
+
throw new Error(`Plugin module does not export a class: ${pluginPath}`);
|
|
37
|
+
}
|
|
38
|
+
const instance = new PluginClass();
|
|
39
|
+
if (typeof instance.run !== 'function') {
|
|
40
|
+
throw new Error(`Plugin does not have a run() method: ${pluginPath}`);
|
|
41
|
+
}
|
|
42
|
+
return instance;
|
|
43
|
+
}
|
|
44
|
+
function findConfigPath(cwd) {
|
|
45
|
+
let dir = cwd;
|
|
46
|
+
for (let i = 0; i < 20; i++) {
|
|
47
|
+
const candidate = (0, path_1.resolve)(dir, 'crewx.yaml');
|
|
48
|
+
try {
|
|
49
|
+
(0, fs_1.readFileSync)(candidate, 'utf8');
|
|
50
|
+
return candidate;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
const parent = (0, path_1.resolve)(dir, '..');
|
|
54
|
+
if (parent === dir)
|
|
55
|
+
break;
|
|
56
|
+
dir = parent;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
function parseProviderFromArgs(args) {
|
|
62
|
+
const idx = args.indexOf('--provider');
|
|
63
|
+
if (idx === -1 || idx + 1 >= args.length) {
|
|
64
|
+
console.error('[crewx] Missing required --provider argument. Usage: hook-dispatch --provider <claude|codex>');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const val = args[idx + 1];
|
|
68
|
+
if (val !== 'claude' && val !== 'codex') {
|
|
69
|
+
console.error(`[crewx] Invalid --provider value: "${val}". Expected: claude | codex`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
return val;
|
|
73
|
+
}
|
|
74
|
+
async function handleHookDispatch(args) {
|
|
75
|
+
const provider = parseProviderFromArgs(args);
|
|
76
|
+
const stdinData = await readStdin();
|
|
77
|
+
let input;
|
|
78
|
+
try {
|
|
79
|
+
input = JSON.parse(stdinData);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
console.error('[crewx] Failed to parse stdin JSON');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const configPath = findConfigPath(input.cwd || process.cwd());
|
|
86
|
+
if (!configPath) {
|
|
87
|
+
const output = {
|
|
88
|
+
hookSpecificOutput: {
|
|
89
|
+
hookEventName: input.hook_event_name,
|
|
90
|
+
permissionDecision: 'allow',
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
process.stdout.write(JSON.stringify(output));
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
const configRoot = (0, path_1.dirname)(configPath);
|
|
97
|
+
let config;
|
|
98
|
+
try {
|
|
99
|
+
config = (0, sdk_1.loadYamlFile)(configPath);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
console.error(`[crewx] Failed to load crewx.yaml: ${configPath}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
const hookDefs = Array.isArray(config.hooks) ? config.hooks : [];
|
|
106
|
+
const matchingDefs = hookDefs.filter((h) => {
|
|
107
|
+
const prov = h.provider;
|
|
108
|
+
if (prov === undefined)
|
|
109
|
+
return true;
|
|
110
|
+
if (typeof prov === 'string')
|
|
111
|
+
return prov === provider;
|
|
112
|
+
if (Array.isArray(prov))
|
|
113
|
+
return prov.includes(provider);
|
|
114
|
+
return false;
|
|
115
|
+
}).filter((h) => h.event === 'PreToolUse' || !h.event);
|
|
116
|
+
if (matchingDefs.length === 0) {
|
|
117
|
+
const output = {
|
|
118
|
+
hookSpecificOutput: {
|
|
119
|
+
hookEventName: input.hook_event_name,
|
|
120
|
+
permissionDecision: 'allow',
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
process.stdout.write(JSON.stringify(output));
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
const guideDefs = matchingDefs.filter((h) => h.guide && typeof h.guide === 'object');
|
|
127
|
+
const pluginDefs = matchingDefs.filter((h) => h.plugin && typeof h.plugin === 'string');
|
|
128
|
+
if (guideDefs.length > 0) {
|
|
129
|
+
const { valid, warnings } = (0, hooks_1.validateHooksSchema)(guideDefs);
|
|
130
|
+
for (const w of warnings) {
|
|
131
|
+
process.stderr.write(`[crewx] ${w}\n`);
|
|
132
|
+
}
|
|
133
|
+
if (valid.length > 0) {
|
|
134
|
+
const agents = Array.isArray(config.agents) ? config.agents : [];
|
|
135
|
+
const yamlPlugin = new hooks_1.YamlHookPlugin({ hooks: valid, agents });
|
|
136
|
+
const result = await (0, hooks_1.evaluateHook)(yamlPlugin, input, configRoot, provider);
|
|
137
|
+
if (result.exitCode !== 0) {
|
|
138
|
+
process.stdout.write(JSON.stringify(result.stdout));
|
|
139
|
+
process.exit(result.exitCode);
|
|
140
|
+
}
|
|
141
|
+
if (result.injected) {
|
|
142
|
+
process.stdout.write(JSON.stringify(result.stdout));
|
|
143
|
+
process.exit(0);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (const hookDef of pluginDefs) {
|
|
148
|
+
const pluginRelPath = hookDef.plugin;
|
|
149
|
+
if (!pluginRelPath) {
|
|
150
|
+
console.error(`[crewx] Hook definition missing 'plugin' field`);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const pluginPath = (0, path_1.resolve)(configRoot, pluginRelPath);
|
|
154
|
+
if (!(0, hooks_1.isPathSafe)(pluginPath, configRoot)) {
|
|
155
|
+
console.error(`[crewx] Hook plugin path rejected (path traversal): ${pluginRelPath}`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
let plugin;
|
|
159
|
+
try {
|
|
160
|
+
plugin = loadPlugin(pluginPath);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.error(`[crewx] Failed to load hook plugin: ${pluginRelPath} — ${err instanceof Error ? err.message : String(err)}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
const result = await (0, hooks_1.evaluateHook)(plugin, input, configRoot, provider);
|
|
167
|
+
if (result.exitCode !== 0) {
|
|
168
|
+
process.stdout.write(JSON.stringify(result.stdout));
|
|
169
|
+
process.exit(result.exitCode);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const output = {
|
|
173
|
+
hookSpecificOutput: {
|
|
174
|
+
hookEventName: input.hook_event_name,
|
|
175
|
+
permissionDecision: 'allow',
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
process.stdout.write(JSON.stringify(output));
|
|
179
|
+
process.exit(0);
|
|
180
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx init handler.
|
|
3
|
+
* Initializes a CrewX project by creating crewx.yaml and supporting dirs.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* crewx init Create crewx.yaml in current directory
|
|
7
|
+
* crewx init --force Overwrite existing configuration
|
|
8
|
+
*/
|
|
9
|
+
export interface InitResult {
|
|
10
|
+
yamlCreated: boolean;
|
|
11
|
+
hookInstalled: boolean;
|
|
12
|
+
errors: string[];
|
|
13
|
+
skippedReason?: 'yaml-exists' | 'nested-project';
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Programmatic init — creates crewx.yaml, support dirs, and optionally installs hooks.
|
|
17
|
+
* Throws on unrecoverable errors (PATH_NOT_FOUND, NESTED_CREWX_PROJECT, YAML_CREATE_FAILED).
|
|
18
|
+
* Partial failures (hook install, mkdir) are collected in InitResult.errors without rollback.
|
|
19
|
+
*/
|
|
20
|
+
export declare function handleInit(opts: {
|
|
21
|
+
path: string;
|
|
22
|
+
skipHook?: boolean;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
}): Promise<InitResult>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx init handler.
|
|
4
|
+
* Initializes a CrewX project by creating crewx.yaml and supporting dirs.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* crewx init Create crewx.yaml in current directory
|
|
8
|
+
* crewx init --force Overwrite existing configuration
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.handleInit = handleInit;
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const install_1 = require("./hook/install");
|
|
15
|
+
const paths_1 = require("./hook/paths");
|
|
16
|
+
const DEFAULT_AGENTS = [
|
|
17
|
+
{
|
|
18
|
+
id: 'planner',
|
|
19
|
+
name: 'Planner',
|
|
20
|
+
role: 'Product/Architecture Planner',
|
|
21
|
+
team: 'core',
|
|
22
|
+
provider: 'cli/claude',
|
|
23
|
+
default_model: 'claude-opus-4-7',
|
|
24
|
+
working_directory: './',
|
|
25
|
+
description: '요구 분석·설계·작업 분해를 담당',
|
|
26
|
+
system_prompt: `You are a planner. Break down user goals into concrete,\ntestable steps. Challenge assumptions. Never write code directly.`,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'developer',
|
|
30
|
+
name: 'Developer',
|
|
31
|
+
role: 'Implementation Engineer',
|
|
32
|
+
team: 'core',
|
|
33
|
+
provider: 'cli/claude',
|
|
34
|
+
default_model: 'claude-opus-4-7',
|
|
35
|
+
working_directory: './',
|
|
36
|
+
description: '실제 코드 작성과 테스트',
|
|
37
|
+
system_prompt: `Implement what the planner specifies. Prefer editing\nexisting files. Run tests before reporting done.`,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'reviewer',
|
|
41
|
+
name: 'Reviewer',
|
|
42
|
+
role: 'Code Reviewer',
|
|
43
|
+
team: 'core',
|
|
44
|
+
provider: 'cli/claude',
|
|
45
|
+
default_model: 'claude-opus-4-7',
|
|
46
|
+
working_directory: './',
|
|
47
|
+
description: '코드 품질·보안·가독성 리뷰',
|
|
48
|
+
system_prompt: `Review diffs for correctness, security, readability.\nCite file:line. Be blunt, not polite.`,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
function escapeYamlBlock(text) {
|
|
52
|
+
return text
|
|
53
|
+
.split('\n')
|
|
54
|
+
.map((line) => ` ${line}`)
|
|
55
|
+
.join('\n');
|
|
56
|
+
}
|
|
57
|
+
function generateDefaultYaml(agents) {
|
|
58
|
+
const agentBlocks = agents
|
|
59
|
+
.map((a) => ` - id: "${a.id}"
|
|
60
|
+
name: "${a.name}"
|
|
61
|
+
role: "${a.role}"
|
|
62
|
+
team: "${a.team}"
|
|
63
|
+
provider: "${a.provider}"
|
|
64
|
+
default_model: "${a.default_model}"
|
|
65
|
+
working_directory: "${a.working_directory}"
|
|
66
|
+
description: "${a.description}"
|
|
67
|
+
system_prompt: |
|
|
68
|
+
${escapeYamlBlock(a.system_prompt)}`)
|
|
69
|
+
.join('\n\n');
|
|
70
|
+
return `# CrewX Agents Configuration
|
|
71
|
+
# Generated by 'crewx init'
|
|
72
|
+
|
|
73
|
+
agents:
|
|
74
|
+
${agentBlocks}
|
|
75
|
+
|
|
76
|
+
# Usage examples:
|
|
77
|
+
# crewx query "@planner analyze this codebase"
|
|
78
|
+
# crewx execute "@developer implement the feature described above"
|
|
79
|
+
# crewx agent ls
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Programmatic init — creates crewx.yaml, support dirs, and optionally installs hooks.
|
|
84
|
+
* Throws on unrecoverable errors (PATH_NOT_FOUND, NESTED_CREWX_PROJECT, YAML_CREATE_FAILED).
|
|
85
|
+
* Partial failures (hook install, mkdir) are collected in InitResult.errors without rollback.
|
|
86
|
+
*/
|
|
87
|
+
async function handleInit(opts) {
|
|
88
|
+
const { path: target, skipHook = false, force = false } = opts;
|
|
89
|
+
const errors = [];
|
|
90
|
+
let yamlCreated = false;
|
|
91
|
+
let hookInstalled = false;
|
|
92
|
+
if (!(0, fs_1.existsSync)(target)) {
|
|
93
|
+
throw new Error(`PATH_NOT_FOUND: ${target}`);
|
|
94
|
+
}
|
|
95
|
+
// Reject if a parent directory already owns a crewx project
|
|
96
|
+
const parentRoot = (0, paths_1.findProjectRoot)((0, path_1.dirname)(target));
|
|
97
|
+
if (parentRoot && parentRoot !== target) {
|
|
98
|
+
throw new Error(`NESTED_CREWX_PROJECT: parent root at ${parentRoot}`);
|
|
99
|
+
}
|
|
100
|
+
const yamlPath = (0, path_1.join)(target, 'crewx.yaml');
|
|
101
|
+
const ymlPath = (0, path_1.join)(target, 'crewx.yml');
|
|
102
|
+
if ((0, fs_1.existsSync)(yamlPath) || (0, fs_1.existsSync)(ymlPath)) {
|
|
103
|
+
if (!force) {
|
|
104
|
+
return { yamlCreated: false, hookInstalled: false, errors: [], skippedReason: 'yaml-exists' };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const content = generateDefaultYaml(DEFAULT_AGENTS);
|
|
109
|
+
(0, fs_1.writeFileSync)(yamlPath, content, 'utf-8');
|
|
110
|
+
yamlCreated = true;
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
throw new Error(`YAML_CREATE_FAILED: ${e.message}`);
|
|
114
|
+
}
|
|
115
|
+
for (const dir of ['.crewx/logs', '.claude/commands']) {
|
|
116
|
+
try {
|
|
117
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(target, dir), { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
errors.push(`MKDIR_FAILED:${dir}:${e.message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!skipHook) {
|
|
124
|
+
try {
|
|
125
|
+
await (0, install_1.handleHookInstall)({ projectRoot: target, yes: true });
|
|
126
|
+
hookInstalled = true;
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
errors.push(`HOOK_INSTALL_FAILED: ${e.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { yamlCreated, hookInstalled, errors };
|
|
133
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx kill handler.
|
|
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
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Handle `crewx kill` command.
|
|
11
|
+
*/
|
|
12
|
+
export declare function handleKill(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.handleKill = handleKill;
|
|
12
|
+
const task_db_1 = require("./task-db");
|
|
13
|
+
/**
|
|
14
|
+
* Handle `crewx kill` command.
|
|
15
|
+
*/
|
|
16
|
+
async function handleKill(args) {
|
|
17
|
+
const killAll = args.includes('--all');
|
|
18
|
+
const taskId = args.find(a => !a.startsWith('--'));
|
|
19
|
+
if (!taskId && !killAll) {
|
|
20
|
+
console.error('Error: Please provide a task ID or use --all to kill all running tasks.');
|
|
21
|
+
console.error('');
|
|
22
|
+
console.error('Usage:');
|
|
23
|
+
console.error(' crewx kill <task-id> Kill a running task by ID');
|
|
24
|
+
console.error(' crewx kill --all Kill all running tasks');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (killAll) {
|
|
29
|
+
const running = (0, task_db_1.getRunningTasks)();
|
|
30
|
+
if (running.length === 0) {
|
|
31
|
+
console.log('No running tasks found.');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log(`Found ${running.length} running task(s). Killing...`);
|
|
35
|
+
for (const task of running) {
|
|
36
|
+
const r = (0, task_db_1.killTask)(task.id);
|
|
37
|
+
console.log(r.message);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const r = (0, task_db_1.killTask)(taskId);
|
|
42
|
+
if (r.ok) {
|
|
43
|
+
console.log(r.message);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.error(`Error: ${r.message}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx log handler.
|
|
3
|
+
* Lists task execution logs or shows a specific task log.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* crewx log List all tasks (newest first)
|
|
7
|
+
* crewx log ls Same as above
|
|
8
|
+
* crewx log <task_id> Show specific task details
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Handle `crewx log` command.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleLog(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx log handler.
|
|
4
|
+
* Lists task execution logs or shows a specific task log.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* crewx log List all tasks (newest first)
|
|
8
|
+
* crewx log ls Same as above
|
|
9
|
+
* crewx log <task_id> Show specific task details
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.handleLog = handleLog;
|
|
13
|
+
const task_db_1 = require("./task-db");
|
|
14
|
+
function statusIcon(status) {
|
|
15
|
+
switch (status) {
|
|
16
|
+
case 'running': return '⏳';
|
|
17
|
+
case 'success': return '✅';
|
|
18
|
+
case 'failed': return '❌';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Handle `crewx log` command.
|
|
23
|
+
*/
|
|
24
|
+
async function handleLog(args) {
|
|
25
|
+
const action = args[0];
|
|
26
|
+
const isTaskId = action && (action.startsWith('tsk_') || action.startsWith('task_'));
|
|
27
|
+
const isListCommand = !action || action === 'ls' || action === 'list';
|
|
28
|
+
if (isTaskId) {
|
|
29
|
+
// Show specific task
|
|
30
|
+
const task = (0, task_db_1.getTask)(action);
|
|
31
|
+
if (!task) {
|
|
32
|
+
console.error(`Task not found: ${action}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
console.log(`\nTask Log\n${'='.repeat(60)}`);
|
|
37
|
+
console.log(`Task ID: ${task.id}`);
|
|
38
|
+
console.log(`Status: ${statusIcon(task.status)} ${task.status}`);
|
|
39
|
+
console.log(`Agent: ${task.agent_id}`);
|
|
40
|
+
console.log(`Mode: ${task.mode}`);
|
|
41
|
+
console.log(`Started: ${new Date(task.started_at).toLocaleString()}`);
|
|
42
|
+
if (task.completed_at) {
|
|
43
|
+
const duration = new Date(task.completed_at).getTime() - new Date(task.started_at).getTime();
|
|
44
|
+
console.log(`Completed: ${new Date(task.completed_at).toLocaleString()} (${duration}ms)`);
|
|
45
|
+
}
|
|
46
|
+
console.log('='.repeat(60));
|
|
47
|
+
console.log('');
|
|
48
|
+
if (task.status === 'success' && task.result) {
|
|
49
|
+
console.log('Result:');
|
|
50
|
+
console.log(task.result);
|
|
51
|
+
}
|
|
52
|
+
else if (task.status === 'failed' && task.error) {
|
|
53
|
+
console.log(`Error: ${task.error}`);
|
|
54
|
+
}
|
|
55
|
+
else if (task.status === 'running') {
|
|
56
|
+
console.log('(task is still running)');
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (isListCommand) {
|
|
61
|
+
const allTasks = (0, task_db_1.getAllTasks)();
|
|
62
|
+
console.log('\nAvailable Task Logs');
|
|
63
|
+
console.log('='.repeat(60));
|
|
64
|
+
const total = allTasks.length;
|
|
65
|
+
const completed = allTasks.filter(t => t.status === 'success').length;
|
|
66
|
+
const failed = allTasks.filter(t => t.status === 'failed').length;
|
|
67
|
+
const running = allTasks.filter(t => t.status === 'running').length;
|
|
68
|
+
console.log(`Total: ${total} | ✅ Completed: ${completed} | ❌ Failed: ${failed} | ⏳ Running: ${running}`);
|
|
69
|
+
console.log('='.repeat(60));
|
|
70
|
+
console.log('');
|
|
71
|
+
if (allTasks.length === 0) {
|
|
72
|
+
console.log('No task logs found.');
|
|
73
|
+
console.log('Tip: Run `crewx query` or `crewx execute` to create tasks.');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
allTasks.forEach((task, idx) => {
|
|
77
|
+
const icon = statusIcon(task.status);
|
|
78
|
+
const duration = task.completed_at
|
|
79
|
+
? `${new Date(task.completed_at).getTime() - new Date(task.started_at).getTime()}ms`
|
|
80
|
+
: 'running...';
|
|
81
|
+
console.log(`${idx + 1}. ${icon} ${task.id}`);
|
|
82
|
+
console.log(` Agent: ${task.agent_id} Mode: ${task.mode}`);
|
|
83
|
+
console.log(` Started: ${new Date(task.started_at).toLocaleString()}`);
|
|
84
|
+
console.log(` Duration: ${duration}`);
|
|
85
|
+
console.log('');
|
|
86
|
+
});
|
|
87
|
+
console.log('Tip: Use "crewx log <task_id>" to view detailed log');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
console.error(`Unknown log action: ${action}`);
|
|
91
|
+
console.error('');
|
|
92
|
+
console.error('Usage:');
|
|
93
|
+
console.error(' crewx log List all logs (default)');
|
|
94
|
+
console.error(' crewx log ls List all logs');
|
|
95
|
+
console.error(' crewx log <task_id> View specific log');
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for parsing agent reference and message from CLI args.
|
|
3
|
+
*
|
|
4
|
+
* Supported call forms:
|
|
5
|
+
* crewx query '@claude 안녕' → agentRef='@claude', message='안녕'
|
|
6
|
+
* crewx query '@claude' '안녕' → agentRef='@claude', message='안녕'
|
|
7
|
+
* crewx query '@claude' '안녕' '해' → agentRef='@claude', message='안녕 해'
|
|
8
|
+
* crewx query '안녕하세요' → agentRef='', message='안녕하세요' (default agent)
|
|
9
|
+
*
|
|
10
|
+
* Only @mention form triggers explicit agent selection. Input without a
|
|
11
|
+
* leading @mention uses the default agent (@crewx) — callers are responsible
|
|
12
|
+
* for applying the fallback.
|
|
13
|
+
*
|
|
14
|
+
* Reusable by query, execute, and any future command that accepts an agent ref.
|
|
15
|
+
*/
|
|
16
|
+
export interface AgentMessage {
|
|
17
|
+
agentRef: string;
|
|
18
|
+
message: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse agent reference and message from CLI args array.
|
|
22
|
+
*
|
|
23
|
+
* Joins all args with a single space first, then splits on the first
|
|
24
|
+
* whitespace boundary so that both the "single-chunk" form
|
|
25
|
+
* (`'@claude 안녕'`) and the "separated" form (`'@claude', '안녕'`) produce
|
|
26
|
+
* identical results.
|
|
27
|
+
*
|
|
28
|
+
* Returns agentRef='' when no leading @mention is found — the caller should
|
|
29
|
+
* default to '@crewx' in that case.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseAgentMessage(args: string[]): AgentMessage;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared utility for parsing agent reference and message from CLI args.
|
|
4
|
+
*
|
|
5
|
+
* Supported call forms:
|
|
6
|
+
* crewx query '@claude 안녕' → agentRef='@claude', message='안녕'
|
|
7
|
+
* crewx query '@claude' '안녕' → agentRef='@claude', message='안녕'
|
|
8
|
+
* crewx query '@claude' '안녕' '해' → agentRef='@claude', message='안녕 해'
|
|
9
|
+
* crewx query '안녕하세요' → agentRef='', message='안녕하세요' (default agent)
|
|
10
|
+
*
|
|
11
|
+
* Only @mention form triggers explicit agent selection. Input without a
|
|
12
|
+
* leading @mention uses the default agent (@crewx) — callers are responsible
|
|
13
|
+
* for applying the fallback.
|
|
14
|
+
*
|
|
15
|
+
* Reusable by query, execute, and any future command that accepts an agent ref.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.parseAgentMessage = parseAgentMessage;
|
|
19
|
+
/**
|
|
20
|
+
* Parse agent reference and message from CLI args array.
|
|
21
|
+
*
|
|
22
|
+
* Joins all args with a single space first, then splits on the first
|
|
23
|
+
* whitespace boundary so that both the "single-chunk" form
|
|
24
|
+
* (`'@claude 안녕'`) and the "separated" form (`'@claude', '안녕'`) produce
|
|
25
|
+
* identical results.
|
|
26
|
+
*
|
|
27
|
+
* Returns agentRef='' when no leading @mention is found — the caller should
|
|
28
|
+
* default to '@crewx' in that case.
|
|
29
|
+
*/
|
|
30
|
+
function parseAgentMessage(args) {
|
|
31
|
+
if (args.length === 0) {
|
|
32
|
+
return { agentRef: '', message: '' };
|
|
33
|
+
}
|
|
34
|
+
// Join all args so both forms are handled uniformly
|
|
35
|
+
const combined = args.join(' ').trim();
|
|
36
|
+
if (!combined) {
|
|
37
|
+
return { agentRef: '', message: '' };
|
|
38
|
+
}
|
|
39
|
+
// Only @mention form triggers explicit agent selection
|
|
40
|
+
if (combined.startsWith('@')) {
|
|
41
|
+
const spaceIdx = combined.indexOf(' ');
|
|
42
|
+
if (spaceIdx === -1) {
|
|
43
|
+
return { agentRef: combined, message: '' };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
agentRef: combined.slice(0, spaceIdx),
|
|
47
|
+
message: combined.slice(spaceIdx + 1).trim(),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// No leading @mention — entire input is the message; caller defaults to @crewx
|
|
51
|
+
return { agentRef: '', message: combined };
|
|
52
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common flag parser for query/execute commands.
|
|
3
|
+
*
|
|
4
|
+
* Supports both `--flag=value` and `--flag value` forms.
|
|
5
|
+
* Handles: --thread, --provider, --metadata, --verbose, --config/-c,
|
|
6
|
+
* --output-format, --effort.
|
|
7
|
+
*/
|
|
8
|
+
export interface CommonFlags {
|
|
9
|
+
/** Thread name for conversation continuity. */
|
|
10
|
+
thread?: string;
|
|
11
|
+
/** Provider override (e.g., cli/claude). */
|
|
12
|
+
provider?: string;
|
|
13
|
+
/** Raw metadata JSON string. */
|
|
14
|
+
metadata?: string;
|
|
15
|
+
/** Enable verbose/debug output mode. */
|
|
16
|
+
verbose: boolean;
|
|
17
|
+
/** Config file path override. */
|
|
18
|
+
config?: string;
|
|
19
|
+
/** Output format (json | text | stream-json). */
|
|
20
|
+
outputFormat?: string;
|
|
21
|
+
/** Model effort level (high | medium | low). */
|
|
22
|
+
effort?: string;
|
|
23
|
+
/** Remaining non-flag arguments. */
|
|
24
|
+
rest: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse common CLI flags from an args array.
|
|
28
|
+
* Returns parsed flags and remaining positional arguments.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseCommonFlags(args: string[]): CommonFlags;
|
|
31
|
+
/**
|
|
32
|
+
* Parse metadata JSON string from --metadata flag.
|
|
33
|
+
* Returns empty object when no raw value provided.
|
|
34
|
+
* Throws Error on invalid JSON or non-object values (fail-fast).
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseMetadata(raw?: string): Record<string, unknown>;
|