@crewx/cli 0.8.4-rc.0 → 0.8.4-rc.1
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/README.md +33 -33
- package/bin/crewx +2 -2
- package/dist/commands/agent.js +23 -23
- package/dist/commands/init.js +20 -20
- 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/main.js +72 -72
- 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 +11 -0
- package/dist/plugins/sqlite-tracing.js +19 -0
- package/dist/repository/workspace.repository.d.ts +26 -0
- package/dist/repository/workspace.repository.js +111 -0
- package/dist/schema/tasks.d.ts +7 -0
- package/dist/schema/tasks.js +48 -0
- package/package.json +18 -18
- package/dist/ai-provider.service.d.ts +0 -34
- package/dist/ai-provider.service.js +0 -311
- 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 +0 -110
- 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 -321
- 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 -379
- 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 -39
- package/dist/cli-options.js +0 -355
- 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-conversation-history.provider.d.ts +0 -16
- package/dist/conversation/cli-conversation-history.provider.js +0 -111
- package/dist/conversation/cli-conversation-history.provider.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 -6
- package/dist/conversation/index.js +0 -27
- 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 -359
- package/dist/crewx.tool.js +0 -2501
- package/dist/crewx.tool.js.map +0 -1
- package/dist/crewx.tool.spec.d.ts +0 -1
- package/dist/crewx.tool.spec.js +0 -158
- 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 -15
- package/dist/providers/dynamic-provider.factory.js +0 -133
- package/dist/providers/dynamic-provider.factory.js.map +0 -1
- package/dist/providers/logger.adapter.d.ts +0 -6
- package/dist/providers/logger.adapter.js +0 -102
- 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 -622
- 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 -21
- package/dist/services/document-loader.service.js +0 -156
- 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 -67
- package/dist/services/skill.service.js +0 -670
- 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 -35
- package/dist/services/skill.service.spec.js.map +0 -1
- package/dist/services/task-management.service.d.ts +0 -65
- package/dist/services/task-management.service.js +0 -288
- 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 -19
- package/dist/services/tool-call.service.js +0 -1061
- package/dist/services/tool-call.service.js.map +0 -1
- package/dist/services/tracing.service.d.ts +0 -200
- package/dist/services/tracing.service.js +0 -1290
- package/dist/services/tracing.service.js.map +0 -1
- package/dist/slack/formatters/message.formatter.d.ts +0 -32
- package/dist/slack/formatters/message.formatter.js +0 -352
- 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 -567
- 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 -4
- package/dist/utils/template-processor.js +0 -266
- 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/README.md
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
# CrewX CLI
|
|
2
|
-
|
|
3
|
-
> Build AI agent teams from your terminal.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@crewx/cli)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
|
|
8
|
-
## Installation
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
npm install -g @crewx/cli
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Quick Start
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
crewx q "@assistant hello"
|
|
18
|
-
crewx x "@coder implement feature X"
|
|
19
|
-
crewx agent list
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Run `crewx --help` for the full list.
|
|
23
|
-
|
|
24
|
-
## What is CrewX?
|
|
25
|
-
|
|
26
|
-
CrewX lets you define AI agents in a single `crewx.yaml` and call them from the terminal.
|
|
27
|
-
|
|
28
|
-
This repository contains the **CrewX CLI** — a thin wrapper over the [`@crewx/sdk`](https://www.npmjs.com/package/@crewx/sdk) runtime (distributed via npm).
|
|
29
|
-
|
|
30
|
-
## License
|
|
31
|
-
|
|
32
|
-
CLI source: [Apache-2.0](LICENSE).
|
|
33
|
-
`@crewx/sdk` runtime: proprietary on npm.
|
|
1
|
+
# CrewX CLI
|
|
2
|
+
|
|
3
|
+
> Build AI agent teams from your terminal.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@crewx/cli)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g @crewx/cli
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
crewx q "@assistant hello"
|
|
18
|
+
crewx x "@coder implement feature X"
|
|
19
|
+
crewx agent list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Run `crewx --help` for the full list.
|
|
23
|
+
|
|
24
|
+
## What is CrewX?
|
|
25
|
+
|
|
26
|
+
CrewX lets you define AI agents in a single `crewx.yaml` and call them from the terminal.
|
|
27
|
+
|
|
28
|
+
This repository contains the **CrewX CLI** — a thin wrapper over the [`@crewx/sdk`](https://www.npmjs.com/package/@crewx/sdk) runtime (distributed via npm).
|
|
29
|
+
|
|
30
|
+
## License
|
|
31
|
+
|
|
32
|
+
CLI source: [Apache-2.0](LICENSE).
|
|
33
|
+
`@crewx/sdk` runtime: proprietary on npm.
|
package/bin/crewx
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
require('../dist/main.js');
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
require('../dist/main.js');
|
package/dist/commands/agent.js
CHANGED
|
@@ -219,28 +219,28 @@ function loadAgentSkills() {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
function printAgentHelp() {
|
|
222
|
-
console.log(`
|
|
223
|
-
CrewX Agent Management
|
|
224
|
-
|
|
225
|
-
Usage:
|
|
226
|
-
crewx agent # List configured agents (default)
|
|
227
|
-
crewx agent ls # List configured agents
|
|
228
|
-
crewx agent list # Alias for ls
|
|
229
|
-
crewx agent prompt <id> # Inspect rendered agent prompt
|
|
230
|
-
|
|
231
|
-
Filter Options (for agent ls):
|
|
232
|
-
--role <value> Filter by agent role (comma-separated for multiple: PM,Dev)
|
|
233
|
-
--team <value> Filter by agent team (comma-separated for multiple)
|
|
234
|
-
--provider <value> Filter by provider (comma-separated, partial match: claude)
|
|
235
|
-
|
|
236
|
-
Examples:
|
|
237
|
-
crewx agent
|
|
238
|
-
crewx agent ls
|
|
239
|
-
crewx agent ls --role=PM
|
|
240
|
-
crewx agent ls --team="CrewX Core 개발팀"
|
|
241
|
-
crewx agent ls --provider=claude
|
|
242
|
-
crewx agent ls --role=PM --provider=claude
|
|
243
|
-
crewx agent ls --role=PM,general
|
|
244
|
-
CREWX_CONFIG=./crewx.yaml crewx agent list
|
|
222
|
+
console.log(`
|
|
223
|
+
CrewX Agent Management
|
|
224
|
+
|
|
225
|
+
Usage:
|
|
226
|
+
crewx agent # List configured agents (default)
|
|
227
|
+
crewx agent ls # List configured agents
|
|
228
|
+
crewx agent list # Alias for ls
|
|
229
|
+
crewx agent prompt <id> # Inspect rendered agent prompt
|
|
230
|
+
|
|
231
|
+
Filter Options (for agent ls):
|
|
232
|
+
--role <value> Filter by agent role (comma-separated for multiple: PM,Dev)
|
|
233
|
+
--team <value> Filter by agent team (comma-separated for multiple)
|
|
234
|
+
--provider <value> Filter by provider (comma-separated, partial match: claude)
|
|
235
|
+
|
|
236
|
+
Examples:
|
|
237
|
+
crewx agent
|
|
238
|
+
crewx agent ls
|
|
239
|
+
crewx agent ls --role=PM
|
|
240
|
+
crewx agent ls --team="CrewX Core 개발팀"
|
|
241
|
+
crewx agent ls --provider=claude
|
|
242
|
+
crewx agent ls --role=PM --provider=claude
|
|
243
|
+
crewx agent ls --role=PM,general
|
|
244
|
+
CREWX_CONFIG=./crewx.yaml crewx agent list
|
|
245
245
|
`.trim());
|
|
246
246
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -64,28 +64,28 @@ function indentBlock(text, spaces) {
|
|
|
64
64
|
}
|
|
65
65
|
function generateDefaultYaml(agents) {
|
|
66
66
|
const agentBlocks = agents
|
|
67
|
-
.map((a) => ` - id: "${a.id}"
|
|
68
|
-
name: "${a.name}"
|
|
69
|
-
role: "${a.role}"
|
|
70
|
-
team: "${a.team}"
|
|
71
|
-
provider: "${a.provider}"
|
|
72
|
-
working_directory: "${a.working_directory}"
|
|
73
|
-
description: "${a.description}"
|
|
74
|
-
inline:
|
|
75
|
-
model: "${a.inline.model}"
|
|
76
|
-
system_prompt: |
|
|
67
|
+
.map((a) => ` - id: "${a.id}"
|
|
68
|
+
name: "${a.name}"
|
|
69
|
+
role: "${a.role}"
|
|
70
|
+
team: "${a.team}"
|
|
71
|
+
provider: "${a.provider}"
|
|
72
|
+
working_directory: "${a.working_directory}"
|
|
73
|
+
description: "${a.description}"
|
|
74
|
+
inline:
|
|
75
|
+
model: "${a.inline.model}"
|
|
76
|
+
system_prompt: |
|
|
77
77
|
${indentBlock(a.inline.system_prompt, 8)}`)
|
|
78
78
|
.join('\n\n');
|
|
79
|
-
return `# CrewX Agents Configuration
|
|
80
|
-
# Generated by 'crewx init'
|
|
81
|
-
|
|
82
|
-
agents:
|
|
83
|
-
${agentBlocks}
|
|
84
|
-
|
|
85
|
-
# Usage examples:
|
|
86
|
-
# crewx query "@planner analyze this codebase"
|
|
87
|
-
# crewx execute "@developer implement the feature described above"
|
|
88
|
-
# crewx agent ls
|
|
79
|
+
return `# CrewX Agents Configuration
|
|
80
|
+
# Generated by 'crewx init'
|
|
81
|
+
|
|
82
|
+
agents:
|
|
83
|
+
${agentBlocks}
|
|
84
|
+
|
|
85
|
+
# Usage examples:
|
|
86
|
+
# crewx query "@planner analyze this codebase"
|
|
87
|
+
# crewx execute "@developer implement the feature described above"
|
|
88
|
+
# crewx agent ls
|
|
89
89
|
`;
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared SQLite helper for ps/kill/result CLI commands.
|
|
3
|
+
* Reads from (or writes to) the global ~/.crewx/crewx.db
|
|
4
|
+
* populated by SqliteTracingPlugin.
|
|
5
|
+
*/
|
|
6
|
+
import BetterSqlite3 from 'better-sqlite3';
|
|
7
|
+
export type TaskStatus = 'running' | 'success' | 'failed';
|
|
8
|
+
export interface TaskRow {
|
|
9
|
+
id: string;
|
|
10
|
+
agent_id: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
mode: string;
|
|
13
|
+
status: TaskStatus;
|
|
14
|
+
pid: number | null;
|
|
15
|
+
started_at: string;
|
|
16
|
+
completed_at: string | null;
|
|
17
|
+
result: string | null;
|
|
18
|
+
error: string | null;
|
|
19
|
+
duration_ms: number | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function getDbPath(dbRoot?: string): string;
|
|
22
|
+
export declare function openDb(readonly?: boolean, dbRoot?: string): InstanceType<typeof BetterSqlite3> | null;
|
|
23
|
+
/** Return all tasks with status='running'. */
|
|
24
|
+
export declare function getRunningTasks(dbRoot?: string): TaskRow[];
|
|
25
|
+
/** Return all tasks ordered by started_at desc. */
|
|
26
|
+
export declare function getAllTasks(dbRoot?: string): TaskRow[];
|
|
27
|
+
/** Return a single task by id, or undefined if not found. */
|
|
28
|
+
export declare function getTask(id: string, dbRoot?: string): TaskRow | undefined;
|
|
29
|
+
/** Send SIGTERM to the task's pid and mark it failed. Returns ok/message. */
|
|
30
|
+
export declare function killTask(id: string, dbRoot?: string): {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
message: string;
|
|
33
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared SQLite helper for ps/kill/result CLI commands.
|
|
4
|
+
* Reads from (or writes to) the global ~/.crewx/crewx.db
|
|
5
|
+
* populated by SqliteTracingPlugin.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.getDbPath = getDbPath;
|
|
12
|
+
exports.openDb = openDb;
|
|
13
|
+
exports.getRunningTasks = getRunningTasks;
|
|
14
|
+
exports.getAllTasks = getAllTasks;
|
|
15
|
+
exports.getTask = getTask;
|
|
16
|
+
exports.killTask = killTask;
|
|
17
|
+
const fs_1 = require("fs");
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const os_1 = require("os");
|
|
20
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
21
|
+
function getDbPath(dbRoot) {
|
|
22
|
+
return (0, path_1.join)(dbRoot ?? (0, os_1.homedir)(), '.crewx', 'crewx.db');
|
|
23
|
+
}
|
|
24
|
+
function openDb(readonly = true, dbRoot) {
|
|
25
|
+
const dbPath = getDbPath(dbRoot);
|
|
26
|
+
if (!(0, fs_1.existsSync)(dbPath))
|
|
27
|
+
return null;
|
|
28
|
+
return new better_sqlite3_1.default(dbPath, { readonly });
|
|
29
|
+
}
|
|
30
|
+
/** Return all tasks with status='running'. */
|
|
31
|
+
function getRunningTasks(dbRoot) {
|
|
32
|
+
const db = openDb(true, dbRoot);
|
|
33
|
+
if (!db)
|
|
34
|
+
return [];
|
|
35
|
+
try {
|
|
36
|
+
return db.prepare(`SELECT id, agent_id, prompt, mode, status, pid, started_at, completed_at,
|
|
37
|
+
result, error, duration_ms
|
|
38
|
+
FROM tasks WHERE status = 'running' ORDER BY started_at DESC`).all();
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
db.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Return all tasks ordered by started_at desc. */
|
|
45
|
+
function getAllTasks(dbRoot) {
|
|
46
|
+
const db = openDb(true, dbRoot);
|
|
47
|
+
if (!db)
|
|
48
|
+
return [];
|
|
49
|
+
try {
|
|
50
|
+
return db.prepare(`SELECT id, agent_id, prompt, mode, status, pid, started_at, completed_at,
|
|
51
|
+
result, error, duration_ms
|
|
52
|
+
FROM tasks ORDER BY started_at DESC`).all();
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
db.close();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Return a single task by id, or undefined if not found. */
|
|
59
|
+
function getTask(id, dbRoot) {
|
|
60
|
+
const db = openDb(true, dbRoot);
|
|
61
|
+
if (!db)
|
|
62
|
+
return undefined;
|
|
63
|
+
try {
|
|
64
|
+
return db.prepare(`SELECT id, agent_id, prompt, mode, status, pid, started_at, completed_at,
|
|
65
|
+
result, error, duration_ms
|
|
66
|
+
FROM tasks WHERE id = ?`).get(id);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
db.close();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Send SIGTERM to the task's pid and mark it failed. Returns ok/message. */
|
|
73
|
+
function killTask(id, dbRoot) {
|
|
74
|
+
const db = openDb(false, dbRoot);
|
|
75
|
+
if (!db)
|
|
76
|
+
return { ok: false, message: `crewx.db not found — no running tasks.` };
|
|
77
|
+
try {
|
|
78
|
+
const task = db.prepare(`SELECT id, status, pid FROM tasks WHERE id = ?`).get(id);
|
|
79
|
+
if (!task) {
|
|
80
|
+
return { ok: false, message: `Task not found: ${id}` };
|
|
81
|
+
}
|
|
82
|
+
if (task.status !== 'running') {
|
|
83
|
+
return { ok: false, message: `Task ${id} is not running (status: ${task.status})` };
|
|
84
|
+
}
|
|
85
|
+
if (task.pid) {
|
|
86
|
+
try {
|
|
87
|
+
process.kill(task.pid, 'SIGTERM');
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const code = err.code;
|
|
91
|
+
if (code !== 'ESRCH') {
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
message: `Failed to kill PID ${task.pid}: ${err instanceof Error ? err.message : String(err)}`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// ESRCH = process already gone — still clean up the record
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
db.prepare(`UPDATE tasks SET status='failed', error='killed by user',
|
|
101
|
+
completed_at=?, pid=NULL WHERE id=?`).run(new Date().toISOString(), id);
|
|
102
|
+
return { ok: true, message: `Killed task ${id}${task.pid ? ` (PID: ${task.pid})` : ''}` };
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
db.close();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DenyIfTouchesSecretsPlugin — Phase 0 demo HookPlugin.
|
|
3
|
+
*
|
|
4
|
+
* Denies Bash tool calls whose command string contains ".env".
|
|
5
|
+
* Pure string matching — trivially bypassable (see README).
|
|
6
|
+
*
|
|
7
|
+
* SECURITY NOTE:
|
|
8
|
+
* Do NOT include tool.input content in deny reasons.
|
|
9
|
+
* Use static messages only to prevent prompt injection.
|
|
10
|
+
* ✅ return ctx.deny('Secrets-related command');
|
|
11
|
+
* ❌ return ctx.deny(`Blocked: ${cmd}`);
|
|
12
|
+
*/
|
|
13
|
+
import { HookPlugin } from '@crewx/sdk/hooks';
|
|
14
|
+
import type { HookContext, HookResult } from '@crewx/sdk/hooks';
|
|
15
|
+
export declare class DenyIfTouchesSecretsPlugin extends HookPlugin {
|
|
16
|
+
readonly name = "deny-secrets";
|
|
17
|
+
readonly version = "0.1.0";
|
|
18
|
+
readonly capabilities: {
|
|
19
|
+
required: readonly ["deny"];
|
|
20
|
+
};
|
|
21
|
+
run(ctx: HookContext): Promise<HookResult>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DenyIfTouchesSecretsPlugin — Phase 0 demo HookPlugin.
|
|
4
|
+
*
|
|
5
|
+
* Denies Bash tool calls whose command string contains ".env".
|
|
6
|
+
* Pure string matching — trivially bypassable (see README).
|
|
7
|
+
*
|
|
8
|
+
* SECURITY NOTE:
|
|
9
|
+
* Do NOT include tool.input content in deny reasons.
|
|
10
|
+
* Use static messages only to prevent prompt injection.
|
|
11
|
+
* ✅ return ctx.deny('Secrets-related command');
|
|
12
|
+
* ❌ return ctx.deny(`Blocked: ${cmd}`);
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DenyIfTouchesSecretsPlugin = void 0;
|
|
16
|
+
const hooks_1 = require("@crewx/sdk/hooks");
|
|
17
|
+
const SECRET_PATTERNS = ['.env', 'credentials.json', 'service-account-key.json'];
|
|
18
|
+
const SHELL_TOOL_NAMES = new Set(['Bash', 'shell', 'local_shell']);
|
|
19
|
+
class DenyIfTouchesSecretsPlugin extends hooks_1.HookPlugin {
|
|
20
|
+
name = 'deny-secrets';
|
|
21
|
+
version = '0.1.0';
|
|
22
|
+
capabilities = { required: ['deny'] };
|
|
23
|
+
async run(ctx) {
|
|
24
|
+
if (!SHELL_TOOL_NAMES.has(ctx.tool.rawName) && ctx.tool.name !== 'shell') {
|
|
25
|
+
return ctx.pass();
|
|
26
|
+
}
|
|
27
|
+
const input = ctx.tool.input;
|
|
28
|
+
const command = input?.command;
|
|
29
|
+
if (typeof command !== 'string') {
|
|
30
|
+
return ctx.pass();
|
|
31
|
+
}
|
|
32
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
33
|
+
if (command.includes(pattern)) {
|
|
34
|
+
return ctx.deny('Secrets-related command');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return ctx.pass();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.DenyIfTouchesSecretsPlugin = DenyIfTouchesSecretsPlugin;
|
package/dist/main.js
CHANGED
|
@@ -218,78 +218,78 @@ async function main() {
|
|
|
218
218
|
process.exit(1);
|
|
219
219
|
}
|
|
220
220
|
function printHelp() {
|
|
221
|
-
console.log(`
|
|
222
|
-
CrewX CLI v${version_1.CLI_VERSION}
|
|
223
|
-
|
|
224
|
-
Usage:
|
|
225
|
-
crewx Launch web dashboard + open browser (default)
|
|
226
|
-
crewx <command> [options]
|
|
227
|
-
|
|
228
|
-
UI Modes:
|
|
229
|
-
crewx Web dashboard (port 8150, random token, auto-open)
|
|
230
|
-
crewx serve [options] Web server (explicit)
|
|
231
|
-
--port <N> Port (default: 8150)
|
|
232
|
-
--token <T> MCP bearer token (⚠️ use --token-file in shared shells)
|
|
233
|
-
--token-file <PATH> Read bearer token from file
|
|
234
|
-
--no-open Do not auto-open browser
|
|
235
|
-
crewx electron [--overlay] Launch Electron (desktop or overlay window)
|
|
236
|
-
|
|
237
|
-
Query / Execute:
|
|
238
|
-
q|query "@agent <message>" Query an agent (quoted single string)
|
|
239
|
-
x|execute "@agent <task>" Execute a task with an agent (quoted single string)
|
|
240
|
-
|
|
241
|
-
@agent is optional — defaults to @crewx when omitted.
|
|
242
|
-
|
|
243
|
-
Common flags:
|
|
244
|
-
--thread <name> Conversation thread
|
|
245
|
-
--provider <cli/xxx> Provider override
|
|
246
|
-
--metadata <json> Extra metadata (JSON object, double-quoted). Propagated to events/hooks/tracing.
|
|
247
|
-
Invalid JSON aborts with exit code 2.
|
|
248
|
-
e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
249
|
-
--verbose Debug output mode (default: raw response only)
|
|
250
|
-
--config/-c <path> Config file path (default: CREWX_CONFIG or crewx.yaml)
|
|
251
|
-
--output-format <fmt> Output format (json|text|stream-json)
|
|
252
|
-
--effort <level> Model effort (high|medium|low)
|
|
253
|
-
-f/--prompt-file <path> Read task body from file (bypasses argv length limits)
|
|
254
|
-
-- End of flags; remaining tokens treated as message text
|
|
255
|
-
e.g. crewx q "@agent label" -- --flag-in-message
|
|
256
|
-
|
|
257
|
-
Agent Management:
|
|
258
|
-
agent ls [options] List configured agents
|
|
259
|
-
--role <value> Filter by role (comma-separated for OR match)
|
|
260
|
-
--team <value> Filter by team (comma-separated for OR match)
|
|
261
|
-
--provider <value> Filter by provider (comma-separated for OR match)
|
|
262
|
-
agent prompt <@id> Show rendered system prompt for an agent
|
|
263
|
-
|
|
264
|
-
Task Management:
|
|
265
|
-
ps List running tasks
|
|
266
|
-
kill <task-id> Kill a running task
|
|
267
|
-
kill --all Kill all running tasks
|
|
268
|
-
result [task-id] Get task result (or list recent tasks)
|
|
269
|
-
|
|
270
|
-
Logs & Diagnostics:
|
|
271
|
-
log [ls|<task-id>] View task logs
|
|
272
|
-
doctor [--config <path>] Run system diagnosis
|
|
273
|
-
init [--force] [--config <p>] Initialize crewx.yaml
|
|
274
|
-
|
|
275
|
-
Built-in Tools:
|
|
276
|
-
memory <args> Memory tool
|
|
277
|
-
search <args> Search tool
|
|
278
|
-
doc <args> Doc tool
|
|
279
|
-
wbs <args> WBS tool
|
|
280
|
-
cron <args> Cron tool
|
|
281
|
-
workflow <args> Workflow tool
|
|
282
|
-
skill <args> Skill tool
|
|
283
|
-
|
|
284
|
-
Hook Platform:
|
|
285
|
-
hook install [--yes] Install PreToolUse hook in .claude/settings.json
|
|
286
|
-
hook uninstall Remove crewx hook from .claude/settings.json
|
|
287
|
-
hook status Show hook installation status and plugins
|
|
288
|
-
hook-dispatch Internal: IPC router called by Claude (stdin→stdout)
|
|
289
|
-
|
|
290
|
-
Global Options:
|
|
291
|
-
--help, -h Show this help
|
|
292
|
-
--version, -v Show version
|
|
221
|
+
console.log(`
|
|
222
|
+
CrewX CLI v${version_1.CLI_VERSION}
|
|
223
|
+
|
|
224
|
+
Usage:
|
|
225
|
+
crewx Launch web dashboard + open browser (default)
|
|
226
|
+
crewx <command> [options]
|
|
227
|
+
|
|
228
|
+
UI Modes:
|
|
229
|
+
crewx Web dashboard (port 8150, random token, auto-open)
|
|
230
|
+
crewx serve [options] Web server (explicit)
|
|
231
|
+
--port <N> Port (default: 8150)
|
|
232
|
+
--token <T> MCP bearer token (⚠️ use --token-file in shared shells)
|
|
233
|
+
--token-file <PATH> Read bearer token from file
|
|
234
|
+
--no-open Do not auto-open browser
|
|
235
|
+
crewx electron [--overlay] Launch Electron (desktop or overlay window)
|
|
236
|
+
|
|
237
|
+
Query / Execute:
|
|
238
|
+
q|query "@agent <message>" Query an agent (quoted single string)
|
|
239
|
+
x|execute "@agent <task>" Execute a task with an agent (quoted single string)
|
|
240
|
+
|
|
241
|
+
@agent is optional — defaults to @crewx when omitted.
|
|
242
|
+
|
|
243
|
+
Common flags:
|
|
244
|
+
--thread <name> Conversation thread
|
|
245
|
+
--provider <cli/xxx> Provider override
|
|
246
|
+
--metadata <json> Extra metadata (JSON object, double-quoted). Propagated to events/hooks/tracing.
|
|
247
|
+
Invalid JSON aborts with exit code 2.
|
|
248
|
+
e.g. --metadata='{"workflow_id":"wf-1"}'
|
|
249
|
+
--verbose Debug output mode (default: raw response only)
|
|
250
|
+
--config/-c <path> Config file path (default: CREWX_CONFIG or crewx.yaml)
|
|
251
|
+
--output-format <fmt> Output format (json|text|stream-json)
|
|
252
|
+
--effort <level> Model effort (high|medium|low)
|
|
253
|
+
-f/--prompt-file <path> Read task body from file (bypasses argv length limits)
|
|
254
|
+
-- End of flags; remaining tokens treated as message text
|
|
255
|
+
e.g. crewx q "@agent label" -- --flag-in-message
|
|
256
|
+
|
|
257
|
+
Agent Management:
|
|
258
|
+
agent ls [options] List configured agents
|
|
259
|
+
--role <value> Filter by role (comma-separated for OR match)
|
|
260
|
+
--team <value> Filter by team (comma-separated for OR match)
|
|
261
|
+
--provider <value> Filter by provider (comma-separated for OR match)
|
|
262
|
+
agent prompt <@id> Show rendered system prompt for an agent
|
|
263
|
+
|
|
264
|
+
Task Management:
|
|
265
|
+
ps List running tasks
|
|
266
|
+
kill <task-id> Kill a running task
|
|
267
|
+
kill --all Kill all running tasks
|
|
268
|
+
result [task-id] Get task result (or list recent tasks)
|
|
269
|
+
|
|
270
|
+
Logs & Diagnostics:
|
|
271
|
+
log [ls|<task-id>] View task logs
|
|
272
|
+
doctor [--config <path>] Run system diagnosis
|
|
273
|
+
init [--force] [--config <p>] Initialize crewx.yaml
|
|
274
|
+
|
|
275
|
+
Built-in Tools:
|
|
276
|
+
memory <args> Memory tool
|
|
277
|
+
search <args> Search tool
|
|
278
|
+
doc <args> Doc tool
|
|
279
|
+
wbs <args> WBS tool
|
|
280
|
+
cron <args> Cron tool
|
|
281
|
+
workflow <args> Workflow tool
|
|
282
|
+
skill <args> Skill tool
|
|
283
|
+
|
|
284
|
+
Hook Platform:
|
|
285
|
+
hook install [--yes] Install PreToolUse hook in .claude/settings.json
|
|
286
|
+
hook uninstall Remove crewx hook from .claude/settings.json
|
|
287
|
+
hook status Show hook installation status and plugins
|
|
288
|
+
hook-dispatch Internal: IPC router called by Claude (stdin→stdout)
|
|
289
|
+
|
|
290
|
+
Global Options:
|
|
291
|
+
--help, -h Show this help
|
|
292
|
+
--version, -v Show version
|
|
293
293
|
`.trim());
|
|
294
294
|
}
|
|
295
295
|
main().catch((err) => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EchoObserverPlugin — Tool observer that echoes events to a JSONL log.
|
|
3
|
+
*
|
|
4
|
+
* Observes tool:before / tool:after events from the Crewx event bus
|
|
5
|
+
* and appends them as JSONL to ~/.crewx/logs/echo-hook.log.
|
|
6
|
+
* Pure observer — no flow control (deny/inject/modify not applicable).
|
|
7
|
+
*/
|
|
8
|
+
import { ToolObserverPlugin } from '@crewx/sdk/hooks';
|
|
9
|
+
import type { ObserverContext, ObserverResult } from '@crewx/sdk/hooks';
|
|
10
|
+
export declare class EchoHookPlugin extends ToolObserverPlugin {
|
|
11
|
+
readonly name = "echo-hook";
|
|
12
|
+
readonly version = "0.0.1";
|
|
13
|
+
readonly on: {
|
|
14
|
+
beforeTool: true;
|
|
15
|
+
afterTool: true;
|
|
16
|
+
beforePrompt: true;
|
|
17
|
+
sessionStart: true;
|
|
18
|
+
};
|
|
19
|
+
private readonly logPath;
|
|
20
|
+
constructor(logDir?: string);
|
|
21
|
+
run(ctx: ObserverContext): Promise<ObserverResult>;
|
|
22
|
+
private ensureLogDir;
|
|
23
|
+
private echo;
|
|
24
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EchoObserverPlugin — Tool observer that echoes events to a JSONL log.
|
|
4
|
+
*
|
|
5
|
+
* Observes tool:before / tool:after events from the Crewx event bus
|
|
6
|
+
* and appends them as JSONL to ~/.crewx/logs/echo-hook.log.
|
|
7
|
+
* Pure observer — no flow control (deny/inject/modify not applicable).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.EchoHookPlugin = void 0;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const os_1 = require("os");
|
|
14
|
+
const hooks_1 = require("@crewx/sdk/hooks");
|
|
15
|
+
class EchoHookPlugin extends hooks_1.ToolObserverPlugin {
|
|
16
|
+
name = 'echo-hook';
|
|
17
|
+
version = '0.0.1';
|
|
18
|
+
on = {
|
|
19
|
+
beforeTool: true,
|
|
20
|
+
afterTool: true,
|
|
21
|
+
beforePrompt: true,
|
|
22
|
+
sessionStart: true,
|
|
23
|
+
};
|
|
24
|
+
logPath;
|
|
25
|
+
constructor(logDir) {
|
|
26
|
+
super();
|
|
27
|
+
this.logPath = (0, path_1.join)(logDir ?? (0, os_1.homedir)(), '.crewx', 'logs', 'echo-hook.log');
|
|
28
|
+
this.ensureLogDir();
|
|
29
|
+
}
|
|
30
|
+
async run(ctx) {
|
|
31
|
+
this.echo(ctx);
|
|
32
|
+
return ctx.pass();
|
|
33
|
+
}
|
|
34
|
+
ensureLogDir() {
|
|
35
|
+
const dir = (0, path_1.dirname)(this.logPath);
|
|
36
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
37
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
echo(ctx) {
|
|
41
|
+
try {
|
|
42
|
+
const line = JSON.stringify({
|
|
43
|
+
timestamp: new Date().toISOString(),
|
|
44
|
+
event: ctx.event,
|
|
45
|
+
traceId: ctx.traceId,
|
|
46
|
+
agent: ctx.agent,
|
|
47
|
+
provider: ctx.provider,
|
|
48
|
+
thread: ctx.thread,
|
|
49
|
+
tool: ctx.tool,
|
|
50
|
+
cwd: ctx.cwd,
|
|
51
|
+
sessionId: ctx.sessionId,
|
|
52
|
+
});
|
|
53
|
+
(0, fs_1.appendFileSync)(this.logPath, line + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Non-fatal
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.EchoHookPlugin = EchoHookPlugin;
|