@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,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx execute handler.
|
|
4
|
+
* Parses args, loads config via Crewx SDK, and executes the task.
|
|
5
|
+
*
|
|
6
|
+
* Flags:
|
|
7
|
+
* --thread <name> Conversation thread name
|
|
8
|
+
* --provider <cli/xxx> Provider override
|
|
9
|
+
* --metadata <json> Extra metadata JSON (double-quoted object). Propagated to events/hooks/tracing.
|
|
10
|
+
* e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
11
|
+
* --verbose Debug output mode (default: raw agent response only)
|
|
12
|
+
* --config/-c <path> Config file path override
|
|
13
|
+
* --output-format <fmt> Output format (json|text|stream-json)
|
|
14
|
+
* --effort <level> Model effort (high|medium|low)
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.handleExecute = handleExecute;
|
|
18
|
+
const sdk_1 = require("@crewx/sdk");
|
|
19
|
+
const parse_agent_message_1 = require("./parse-agent-message");
|
|
20
|
+
const parse_common_flags_1 = require("./parse-common-flags");
|
|
21
|
+
const crewx_cli_1 = require("../bootstrap/crewx-cli");
|
|
22
|
+
/**
|
|
23
|
+
* Handle `crewx execute <agentRef> <message>` command.
|
|
24
|
+
*
|
|
25
|
+
* Default output: raw agent response only (stdout).
|
|
26
|
+
* --verbose: debug info written to stderr, response to stdout.
|
|
27
|
+
*/
|
|
28
|
+
async function handleExecute(args) {
|
|
29
|
+
const { thread, provider, metadata, verbose, config, outputFormat, effort, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
|
|
30
|
+
const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
|
|
31
|
+
// No @mention → default to @crewx agent (matches cli-bak behaviour)
|
|
32
|
+
const agentRef = parsedAgentRef || '@crewx';
|
|
33
|
+
if (!message) {
|
|
34
|
+
console.error('Usage: crewx execute [@agent] <task> [options]');
|
|
35
|
+
console.error(' crewx x [@agent] <task> [options]');
|
|
36
|
+
console.error('');
|
|
37
|
+
console.error(' @agent is optional. Defaults to @crewx when omitted.');
|
|
38
|
+
console.error('');
|
|
39
|
+
console.error('Options:');
|
|
40
|
+
console.error(' --thread <name> Conversation thread name');
|
|
41
|
+
console.error(' --provider <cli/xxx> Provider override');
|
|
42
|
+
console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
|
|
43
|
+
console.error(' Propagated to events/hooks/tracing.');
|
|
44
|
+
console.error(' Invalid JSON aborts with exit code 2.');
|
|
45
|
+
console.error(' e.g. --metadata=\'{"workflow_id":"wf-1"}\'');
|
|
46
|
+
console.error(' --verbose Debug output mode');
|
|
47
|
+
console.error(' --config/-c <path> Config file path');
|
|
48
|
+
console.error(' --output-format <fmt> Output format (json|text|stream-json)');
|
|
49
|
+
console.error(' --effort <level> Model effort (high|medium|low)');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
|
|
53
|
+
// Only show exec audit span JSON in verbose mode
|
|
54
|
+
(0, sdk_1.setAuditVerbose)(verbose);
|
|
55
|
+
const crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
|
|
56
|
+
// file:// remote agent delegation is handled transparently inside Crewx.query/execute.
|
|
57
|
+
if (verbose) {
|
|
58
|
+
process.stderr.write(`📋 Task: ${message}\n`);
|
|
59
|
+
process.stderr.write(`🤖 Agent: ${agentRef}\n`);
|
|
60
|
+
if (thread)
|
|
61
|
+
process.stderr.write(`🔗 Thread: ${thread}\n`);
|
|
62
|
+
if (provider)
|
|
63
|
+
process.stderr.write(`🔌 Provider: ${provider}\n`);
|
|
64
|
+
if (outputFormat)
|
|
65
|
+
process.stderr.write(`📄 Output-format: ${outputFormat}\n`);
|
|
66
|
+
if (effort)
|
|
67
|
+
process.stderr.write(`⚡ Effort: ${effort}\n`);
|
|
68
|
+
process.stderr.write('─'.repeat(60) + '\n');
|
|
69
|
+
}
|
|
70
|
+
let parsedMetadata = {};
|
|
71
|
+
try {
|
|
72
|
+
parsedMetadata = (0, parse_common_flags_1.parseMetadata)(metadata);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
76
|
+
process.stderr.write(`Error: ${msg}\n`);
|
|
77
|
+
process.exit(2);
|
|
78
|
+
}
|
|
79
|
+
let exitCode = 0;
|
|
80
|
+
try {
|
|
81
|
+
const result = await crewx.execute(agentRef, message, {
|
|
82
|
+
provider,
|
|
83
|
+
threadId: thread,
|
|
84
|
+
metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
|
|
85
|
+
});
|
|
86
|
+
if (!result.ok) {
|
|
87
|
+
const errMsg = result.error?.message ?? 'Execute failed';
|
|
88
|
+
console.error(errMsg);
|
|
89
|
+
exitCode = 1;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
if (verbose) {
|
|
93
|
+
process.stderr.write(`\n📊 Results from ${agentRef}:\n`);
|
|
94
|
+
process.stderr.write('═'.repeat(60) + '\n');
|
|
95
|
+
process.stderr.write('🟢 Status: Success\n');
|
|
96
|
+
process.stderr.write(`🤖 Provider: ${result.meta.provider}\n`);
|
|
97
|
+
process.stderr.write(`⏱️ Duration: ${result.meta.durationMs}ms\n`);
|
|
98
|
+
process.stderr.write('\n📄 Response:\n');
|
|
99
|
+
process.stderr.write('─'.repeat(40) + '\n');
|
|
100
|
+
}
|
|
101
|
+
console.log(result.data);
|
|
102
|
+
if (verbose) {
|
|
103
|
+
process.stderr.write('\n✅ Execute completed successfully\n');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
109
|
+
console.error(`Error: ${errMsg}`);
|
|
110
|
+
exitCode = 1;
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
await crewx.close();
|
|
114
|
+
}
|
|
115
|
+
if (exitCode !== 0)
|
|
116
|
+
process.exit(exitCode);
|
|
117
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx hook install — Register crewx-hook-dispatch as a PreToolUse hook
|
|
3
|
+
* in <projectRoot>/.claude/settings.json and/or <projectRoot>/.codex/hooks.json.
|
|
4
|
+
*
|
|
5
|
+
* Security:
|
|
6
|
+
* - Prompts user before modifying settings (R1)
|
|
7
|
+
* - Uses absolute path for crewx binary (PATH manipulation prevention)
|
|
8
|
+
* - Backs up original settings files
|
|
9
|
+
* - Preserves existing user hooks
|
|
10
|
+
* - Never traverses parent directories — project root determined by crewx.yaml
|
|
11
|
+
*/
|
|
12
|
+
import { type HookProvider } from './paths';
|
|
13
|
+
export declare const CREWX_HOOK_COMMAND_MARKER = "crewx hook-dispatch";
|
|
14
|
+
export declare function resolveCrewxBinary(): string;
|
|
15
|
+
export interface HookInstallOpts {
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
yes: boolean;
|
|
18
|
+
provider?: HookProvider;
|
|
19
|
+
}
|
|
20
|
+
export declare function handleHookInstall(opts: HookInstallOpts): Promise<void>;
|
|
21
|
+
export declare function handleHookInstall(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx hook install — Register crewx-hook-dispatch as a PreToolUse hook
|
|
4
|
+
* in <projectRoot>/.claude/settings.json and/or <projectRoot>/.codex/hooks.json.
|
|
5
|
+
*
|
|
6
|
+
* Security:
|
|
7
|
+
* - Prompts user before modifying settings (R1)
|
|
8
|
+
* - Uses absolute path for crewx binary (PATH manipulation prevention)
|
|
9
|
+
* - Backs up original settings files
|
|
10
|
+
* - Preserves existing user hooks
|
|
11
|
+
* - Never traverses parent directories — project root determined by crewx.yaml
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.CREWX_HOOK_COMMAND_MARKER = void 0;
|
|
48
|
+
exports.resolveCrewxBinary = resolveCrewxBinary;
|
|
49
|
+
exports.handleHookInstall = handleHookInstall;
|
|
50
|
+
const fs_1 = require("fs");
|
|
51
|
+
const path_1 = require("path");
|
|
52
|
+
const cp = __importStar(require("child_process"));
|
|
53
|
+
const paths_1 = require("./paths");
|
|
54
|
+
exports.CREWX_HOOK_COMMAND_MARKER = 'crewx hook-dispatch';
|
|
55
|
+
function getProviderConfigs(projectRoot, providers, crewxBin) {
|
|
56
|
+
return providers.map((provider) => ({
|
|
57
|
+
settingsPath: provider === 'claude'
|
|
58
|
+
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
59
|
+
: (0, paths_1.getCodexHooksPath)(projectRoot),
|
|
60
|
+
provider,
|
|
61
|
+
matcher: provider === 'claude' ? '' : 'Bash',
|
|
62
|
+
commandArg: `--provider ${provider}`,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
function resolveCrewxBinary() {
|
|
66
|
+
if (process.env.CREWX_CLI)
|
|
67
|
+
return process.env.CREWX_CLI;
|
|
68
|
+
try {
|
|
69
|
+
const which = cp.execSync('which crewx 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
70
|
+
const isTmpProxy = which.includes('/T/crewx-proxy-') ||
|
|
71
|
+
which.includes('/tmp/crewx-proxy-') ||
|
|
72
|
+
/\/[Tt]e?mp\//.test(which);
|
|
73
|
+
if (which && !isTmpProxy)
|
|
74
|
+
return which;
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
if (process.argv[1]) {
|
|
78
|
+
const scriptPath = (0, path_1.resolve)(process.argv[1]);
|
|
79
|
+
if ((0, fs_1.existsSync)(scriptPath)) {
|
|
80
|
+
return `${process.execPath} ${scriptPath}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return 'crewx';
|
|
84
|
+
}
|
|
85
|
+
function readSettingsTyped(settingsPath) {
|
|
86
|
+
return (0, paths_1.readSettings)(settingsPath);
|
|
87
|
+
}
|
|
88
|
+
function findCrewxEntry(preToolUse) {
|
|
89
|
+
if (!preToolUse)
|
|
90
|
+
return -1;
|
|
91
|
+
return preToolUse.findIndex((entry) => entry.hooks?.some((h) => h.command?.includes(exports.CREWX_HOOK_COMMAND_MARKER)));
|
|
92
|
+
}
|
|
93
|
+
function installForProvider(projectRoot, config, crewxBin, yes) {
|
|
94
|
+
const { settingsPath, provider, matcher, commandArg } = config;
|
|
95
|
+
const settings = readSettingsTyped(settingsPath);
|
|
96
|
+
if (!settings.hooks)
|
|
97
|
+
settings.hooks = {};
|
|
98
|
+
if (!settings.hooks.PreToolUse)
|
|
99
|
+
settings.hooks.PreToolUse = [];
|
|
100
|
+
const existingIdx = findCrewxEntry(settings.hooks.PreToolUse);
|
|
101
|
+
if (existingIdx >= 0) {
|
|
102
|
+
console.log(`[crewx] Hook already installed in ${settingsPath} (${provider})`);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (!yes) {
|
|
106
|
+
console.log(`⚠️ crewx hook install will register crewx-hook-dispatch as a PreToolUse hook.\n` +
|
|
107
|
+
` This gives crewx authority to allow/deny ALL ${provider} tool calls.\n` +
|
|
108
|
+
` ${settingsPath} will be patched (backup at ${settingsPath}.crewx-backup).\n`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if ((0, fs_1.existsSync)(settingsPath)) {
|
|
112
|
+
const backupPath = settingsPath + '.crewx-backup';
|
|
113
|
+
(0, fs_1.copyFileSync)(settingsPath, backupPath);
|
|
114
|
+
console.log(`[crewx] Backup created: ${backupPath}`);
|
|
115
|
+
}
|
|
116
|
+
if (provider === 'claude') {
|
|
117
|
+
(0, paths_1.ensureClaudeSettings)(projectRoot);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
(0, paths_1.ensureCodexHooks)(projectRoot);
|
|
121
|
+
}
|
|
122
|
+
const command = `${crewxBin} hook-dispatch ${commandArg}`;
|
|
123
|
+
settings.hooks.PreToolUse.push({
|
|
124
|
+
matcher,
|
|
125
|
+
hooks: [{ type: 'command', command }],
|
|
126
|
+
});
|
|
127
|
+
(0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
|
128
|
+
console.log(`[crewx] Hook installed (${provider}): ${command}`);
|
|
129
|
+
console.log(`[crewx] Settings: ${settingsPath}`);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
async function handleHookInstall(argsOrOpts) {
|
|
133
|
+
if (!Array.isArray(argsOrOpts)) {
|
|
134
|
+
const { projectRoot, yes, provider } = argsOrOpts;
|
|
135
|
+
const providers = (0, paths_1.providersFromFilter)(provider ?? 'all');
|
|
136
|
+
const crewxBin = resolveCrewxBinary();
|
|
137
|
+
const configs = getProviderConfigs(projectRoot, providers, crewxBin);
|
|
138
|
+
for (const config of configs) {
|
|
139
|
+
installForProvider(projectRoot, config, crewxBin, yes);
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const args = argsOrOpts;
|
|
144
|
+
const yes = args.includes('--yes') || args.includes('-y');
|
|
145
|
+
const cwd = process.cwd();
|
|
146
|
+
const projectRoot = (0, paths_1.findProjectRoot)(cwd);
|
|
147
|
+
if (!projectRoot) {
|
|
148
|
+
console.error('[crewx] No crewx.yaml found in current or ancestor directories.');
|
|
149
|
+
console.error('[crewx] Run this command from within a CrewX project.');
|
|
150
|
+
process.exitCode = 1;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const providerFilter = (0, paths_1.parseProviderArg)(args);
|
|
154
|
+
const providers = (0, paths_1.providersFromFilter)(providerFilter);
|
|
155
|
+
const crewxBin = resolveCrewxBinary();
|
|
156
|
+
const configs = getProviderConfigs(projectRoot, providers, crewxBin);
|
|
157
|
+
if (!yes) {
|
|
158
|
+
const targets = configs.map((c) => ` - ${c.provider}: ${c.settingsPath}`).join('\n');
|
|
159
|
+
console.log(`⚠️ crewx hook install will register crewx-hook-dispatch as a PreToolUse hook.\n` +
|
|
160
|
+
` This gives crewx authority to allow/deny ALL tool calls.\n` +
|
|
161
|
+
` Target providers: ${providers.join(', ')}\n` +
|
|
162
|
+
`${targets}\n`);
|
|
163
|
+
process.stdout.write('Continue? [y/N] ');
|
|
164
|
+
const answer = await new Promise((resolve) => {
|
|
165
|
+
process.stdin.once('data', (data) => resolve(data.toString().trim().toLowerCase()));
|
|
166
|
+
});
|
|
167
|
+
if (answer !== 'y' && answer !== 'yes') {
|
|
168
|
+
console.log('Aborted.');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
for (const config of configs) {
|
|
173
|
+
installForProvider(projectRoot, config, crewxBin, true);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path helpers for hook CLI commands.
|
|
3
|
+
*
|
|
4
|
+
* Project root = nearest ancestor containing crewx.yaml.
|
|
5
|
+
* Claude settings path = <projectRoot>/.claude/settings.json
|
|
6
|
+
* Codex hooks path = <projectRoot>/.codex/hooks.json
|
|
7
|
+
*/
|
|
8
|
+
export type HookProvider = 'claude' | 'codex';
|
|
9
|
+
export type HookProviderFilter = HookProvider | 'all';
|
|
10
|
+
export declare function parseProviderArg(args: string[]): HookProviderFilter;
|
|
11
|
+
export declare function providersFromFilter(filter: HookProviderFilter): HookProvider[];
|
|
12
|
+
export declare function findProjectRoot(cwd: string): string | null;
|
|
13
|
+
export declare function getClaudeSettingsPath(projectRoot: string): string;
|
|
14
|
+
export declare function getCodexHooksPath(projectRoot: string): string;
|
|
15
|
+
export declare function getProviderSettingsPath(projectRoot: string, provider: HookProvider): string;
|
|
16
|
+
export declare function readSettings(settingsPath: string): Record<string, unknown>;
|
|
17
|
+
export declare function ensureClaudeSettings(projectRoot: string): string;
|
|
18
|
+
export declare function ensureCodexHooks(projectRoot: string): string;
|
|
19
|
+
export declare function ensureProviderSettings(projectRoot: string, provider: HookProvider): string;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared path helpers for hook CLI commands.
|
|
4
|
+
*
|
|
5
|
+
* Project root = nearest ancestor containing crewx.yaml.
|
|
6
|
+
* Claude settings path = <projectRoot>/.claude/settings.json
|
|
7
|
+
* Codex hooks path = <projectRoot>/.codex/hooks.json
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.parseProviderArg = parseProviderArg;
|
|
11
|
+
exports.providersFromFilter = providersFromFilter;
|
|
12
|
+
exports.findProjectRoot = findProjectRoot;
|
|
13
|
+
exports.getClaudeSettingsPath = getClaudeSettingsPath;
|
|
14
|
+
exports.getCodexHooksPath = getCodexHooksPath;
|
|
15
|
+
exports.getProviderSettingsPath = getProviderSettingsPath;
|
|
16
|
+
exports.readSettings = readSettings;
|
|
17
|
+
exports.ensureClaudeSettings = ensureClaudeSettings;
|
|
18
|
+
exports.ensureCodexHooks = ensureCodexHooks;
|
|
19
|
+
exports.ensureProviderSettings = ensureProviderSettings;
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = require("path");
|
|
22
|
+
function parseProviderArg(args) {
|
|
23
|
+
const idx = args.indexOf('--provider');
|
|
24
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
25
|
+
return 'all';
|
|
26
|
+
const val = args[idx + 1];
|
|
27
|
+
if (val === 'claude' || val === 'codex')
|
|
28
|
+
return val;
|
|
29
|
+
console.error(`[crewx] Invalid --provider value: "${val}". Expected: claude | codex`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
function providersFromFilter(filter) {
|
|
33
|
+
return filter === 'all' ? ['claude', 'codex'] : [filter];
|
|
34
|
+
}
|
|
35
|
+
function findProjectRoot(cwd) {
|
|
36
|
+
let dir = (0, path_1.resolve)(cwd);
|
|
37
|
+
for (;;) {
|
|
38
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(dir, 'crewx.yaml')))
|
|
39
|
+
return dir;
|
|
40
|
+
const parent = (0, path_1.dirname)(dir);
|
|
41
|
+
if (parent === dir)
|
|
42
|
+
break;
|
|
43
|
+
dir = parent;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function getClaudeSettingsPath(projectRoot) {
|
|
48
|
+
return (0, path_1.resolve)(projectRoot, '.claude', 'settings.json');
|
|
49
|
+
}
|
|
50
|
+
function getCodexHooksPath(projectRoot) {
|
|
51
|
+
return (0, path_1.resolve)(projectRoot, '.codex', 'hooks.json');
|
|
52
|
+
}
|
|
53
|
+
function getProviderSettingsPath(projectRoot, provider) {
|
|
54
|
+
return provider === 'claude'
|
|
55
|
+
? getClaudeSettingsPath(projectRoot)
|
|
56
|
+
: getCodexHooksPath(projectRoot);
|
|
57
|
+
}
|
|
58
|
+
function readSettings(settingsPath) {
|
|
59
|
+
if (!(0, fs_1.existsSync)(settingsPath))
|
|
60
|
+
return {};
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf8'));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function ensureClaudeSettings(projectRoot) {
|
|
69
|
+
const settingsPath = getClaudeSettingsPath(projectRoot);
|
|
70
|
+
const settingsDir = (0, path_1.dirname)(settingsPath);
|
|
71
|
+
if (!(0, fs_1.existsSync)(settingsDir)) {
|
|
72
|
+
(0, fs_1.mkdirSync)(settingsDir, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
if (!(0, fs_1.existsSync)(settingsPath)) {
|
|
75
|
+
(0, fs_1.writeFileSync)(settingsPath, '{}\n', 'utf8');
|
|
76
|
+
}
|
|
77
|
+
return settingsPath;
|
|
78
|
+
}
|
|
79
|
+
function ensureCodexHooks(projectRoot) {
|
|
80
|
+
const hooksPath = getCodexHooksPath(projectRoot);
|
|
81
|
+
const hooksDir = (0, path_1.dirname)(hooksPath);
|
|
82
|
+
if (!(0, fs_1.existsSync)(hooksDir)) {
|
|
83
|
+
(0, fs_1.mkdirSync)(hooksDir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
if (!(0, fs_1.existsSync)(hooksPath)) {
|
|
86
|
+
(0, fs_1.writeFileSync)(hooksPath, '{}\n', 'utf8');
|
|
87
|
+
}
|
|
88
|
+
return hooksPath;
|
|
89
|
+
}
|
|
90
|
+
function ensureProviderSettings(projectRoot, provider) {
|
|
91
|
+
return provider === 'claude'
|
|
92
|
+
? ensureClaudeSettings(projectRoot)
|
|
93
|
+
: ensureCodexHooks(projectRoot);
|
|
94
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx hook status — Show hook installation status and registered plugins.
|
|
3
|
+
*
|
|
4
|
+
* Displays status for both Claude (.claude/settings.json) and
|
|
5
|
+
* Codex (.codex/hooks.json) provider settings.
|
|
6
|
+
*/
|
|
7
|
+
export declare function handleHookStatus(_args: string[]): Promise<void>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx hook status — Show hook installation status and registered plugins.
|
|
4
|
+
*
|
|
5
|
+
* Displays status for both Claude (.claude/settings.json) and
|
|
6
|
+
* Codex (.codex/hooks.json) provider settings.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.handleHookStatus = handleHookStatus;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const sdk_1 = require("@crewx/sdk");
|
|
13
|
+
const paths_1 = require("./paths");
|
|
14
|
+
const CREWX_HOOK_COMMAND_MARKER = 'crewx hook-dispatch';
|
|
15
|
+
function showProviderStatus(projectRoot, provider) {
|
|
16
|
+
const settingsPath = provider === 'claude'
|
|
17
|
+
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
18
|
+
: (0, paths_1.getCodexHooksPath)(projectRoot);
|
|
19
|
+
console.log(` [${provider.toUpperCase()}]`);
|
|
20
|
+
if (!(0, fs_1.existsSync)(settingsPath)) {
|
|
21
|
+
console.log(` Settings: not found (${settingsPath})`);
|
|
22
|
+
console.log(` Status: NOT INSTALLED`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log(` Settings: ${settingsPath}`);
|
|
26
|
+
try {
|
|
27
|
+
const settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf8'));
|
|
28
|
+
const preHooks = settings.hooks?.PreToolUse ?? [];
|
|
29
|
+
const crewxEntry = preHooks.find((entry) => entry.hooks?.some((h) => h.command?.includes(CREWX_HOOK_COMMAND_MARKER)));
|
|
30
|
+
if (crewxEntry) {
|
|
31
|
+
const command = crewxEntry.hooks.find((h) => h.command?.includes(CREWX_HOOK_COMMAND_MARKER))?.command;
|
|
32
|
+
console.log(` Status: INSTALLED`);
|
|
33
|
+
console.log(` Command: ${command}`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log(` Status: NOT INSTALLED`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
console.log(` Status: ERROR (failed to parse settings)`);
|
|
41
|
+
}
|
|
42
|
+
const backupPath = settingsPath + '.crewx-backup';
|
|
43
|
+
if ((0, fs_1.existsSync)(backupPath)) {
|
|
44
|
+
console.log(` Backup: ${backupPath}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function handleHookStatus(_args) {
|
|
48
|
+
const cwd = process.cwd();
|
|
49
|
+
const projectRoot = (0, paths_1.findProjectRoot)(cwd);
|
|
50
|
+
if (!projectRoot) {
|
|
51
|
+
console.error('[crewx] No crewx.yaml found in current or ancestor directories.');
|
|
52
|
+
console.error('[crewx] Run this command from within a CrewX project.');
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log('Hook Installation Status');
|
|
57
|
+
console.log('─'.repeat(40));
|
|
58
|
+
showProviderStatus(projectRoot, 'claude');
|
|
59
|
+
showProviderStatus(projectRoot, 'codex');
|
|
60
|
+
const configPath = (0, path_1.resolve)(projectRoot, 'crewx.yaml');
|
|
61
|
+
console.log('');
|
|
62
|
+
console.log('Registered HookPlugins (crewx.yaml)');
|
|
63
|
+
console.log('─'.repeat(40));
|
|
64
|
+
console.log(` Config: ${configPath}`);
|
|
65
|
+
let config;
|
|
66
|
+
try {
|
|
67
|
+
config = (0, sdk_1.loadYamlFile)(configPath);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
console.log(' ERROR: failed to parse crewx.yaml');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const hookDefs = Array.isArray(config.hooks) ? config.hooks : [];
|
|
74
|
+
if (hookDefs.length === 0) {
|
|
75
|
+
console.log(' No hooks defined in crewx.yaml');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
for (const hook of hookDefs) {
|
|
79
|
+
console.log(` - provider: ${hook.provider ?? '(any)'}`);
|
|
80
|
+
console.log(` event: ${hook.event ?? 'PreToolUse'}`);
|
|
81
|
+
console.log(` plugin: ${hook.plugin ?? '(undefined)'}`);
|
|
82
|
+
if (hook.agents) {
|
|
83
|
+
console.log(` agents: ${JSON.stringify(hook.agents)} (reserved — Phase 1)`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx hook uninstall — Remove crewx-hook-dispatch from provider settings files.
|
|
3
|
+
*
|
|
4
|
+
* Only removes entries whose command contains the crewx hook-dispatch marker.
|
|
5
|
+
* Preserves all other user hooks. Cleans up empty PreToolUse/hooks fields.
|
|
6
|
+
* Never traverses parent directories — project root determined by crewx.yaml.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleHookUninstall(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* crewx hook uninstall — Remove crewx-hook-dispatch from provider settings files.
|
|
4
|
+
*
|
|
5
|
+
* Only removes entries whose command contains the crewx hook-dispatch marker.
|
|
6
|
+
* Preserves all other user hooks. Cleans up empty PreToolUse/hooks fields.
|
|
7
|
+
* Never traverses parent directories — project root determined by crewx.yaml.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.handleHookUninstall = handleHookUninstall;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const paths_1 = require("./paths");
|
|
13
|
+
const CREWX_HOOK_COMMAND_MARKER = 'crewx hook-dispatch';
|
|
14
|
+
function getSettingsPath(projectRoot, provider) {
|
|
15
|
+
return provider === 'claude'
|
|
16
|
+
? (0, paths_1.getClaudeSettingsPath)(projectRoot)
|
|
17
|
+
: (0, paths_1.getCodexHooksPath)(projectRoot);
|
|
18
|
+
}
|
|
19
|
+
function uninstallFromProvider(projectRoot, provider) {
|
|
20
|
+
const settingsPath = getSettingsPath(projectRoot, provider);
|
|
21
|
+
if (!(0, fs_1.existsSync)(settingsPath)) {
|
|
22
|
+
console.log(`[crewx] No settings file found for ${provider} (${settingsPath})`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let settings;
|
|
26
|
+
try {
|
|
27
|
+
settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
console.error(`[crewx] Failed to parse ${settingsPath}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!settings.hooks?.PreToolUse?.length) {
|
|
34
|
+
console.log(`[crewx] No PreToolUse hooks found for ${provider}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const before = settings.hooks.PreToolUse.length;
|
|
38
|
+
settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter((entry) => !entry.hooks?.some((h) => h.command?.includes(CREWX_HOOK_COMMAND_MARKER)));
|
|
39
|
+
const removed = settings.hooks.PreToolUse.length < before;
|
|
40
|
+
if (settings.hooks.PreToolUse.length === 0) {
|
|
41
|
+
delete settings.hooks.PreToolUse;
|
|
42
|
+
}
|
|
43
|
+
if (settings.hooks && Object.keys(settings.hooks).length === 0) {
|
|
44
|
+
delete settings.hooks;
|
|
45
|
+
}
|
|
46
|
+
if (!removed) {
|
|
47
|
+
console.log(`[crewx] crewx hook not found for ${provider}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
(0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
|
51
|
+
console.log(`[crewx] Hook uninstalled (${provider})`);
|
|
52
|
+
const backupPath = settingsPath + '.crewx-backup';
|
|
53
|
+
if ((0, fs_1.existsSync)(backupPath)) {
|
|
54
|
+
console.log(`[crewx] Backup available: ${backupPath}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function handleHookUninstall(args) {
|
|
58
|
+
const cwd = process.cwd();
|
|
59
|
+
const projectRoot = (0, paths_1.findProjectRoot)(cwd);
|
|
60
|
+
if (!projectRoot) {
|
|
61
|
+
console.error('[crewx] No crewx.yaml found in current or ancestor directories.');
|
|
62
|
+
console.error('[crewx] Run this command from within a CrewX project.');
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const providerFilter = (0, paths_1.parseProviderArg)(args);
|
|
67
|
+
const providers = (0, paths_1.providersFromFilter)(providerFilter);
|
|
68
|
+
for (const provider of providers) {
|
|
69
|
+
uninstallFromProvider(projectRoot, provider);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* crewx hook-dispatch — CLI subcommand invoked by Claude/Codex PreToolUse hook.
|
|
3
|
+
*
|
|
4
|
+
* Reads stdin JSON from the provider, loads HookPlugins from crewx.yaml,
|
|
5
|
+
* evaluates them, and writes stdout JSON response back.
|
|
6
|
+
*
|
|
7
|
+
* Protocol:
|
|
8
|
+
* stdin → ClaudeHookInput JSON
|
|
9
|
+
* stdout → ClaudeHookOutput JSON
|
|
10
|
+
* exit 0 → allow, exit 2 → deny
|
|
11
|
+
*
|
|
12
|
+
* Security (M1):
|
|
13
|
+
* --provider argument is REQUIRED. Missing → process.exit(1) fail-closed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleHookDispatch(args: string[]): Promise<void>;
|