@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.
Files changed (281) hide show
  1. package/bin/crewx +2 -0
  2. package/dist/bootstrap/crewx-cli.d.ts +11 -0
  3. package/dist/bootstrap/crewx-cli.js +31 -0
  4. package/dist/builtin.d.ts +15 -0
  5. package/dist/{cli/builtin.handler.js → builtin.js} +21 -7
  6. package/dist/commands/agent.d.ts +12 -0
  7. package/dist/commands/agent.js +246 -0
  8. package/dist/commands/doctor.d.ts +12 -0
  9. package/dist/commands/doctor.js +190 -0
  10. package/dist/commands/execute.d.ts +21 -0
  11. package/dist/commands/execute.js +117 -0
  12. package/dist/commands/hook/install.d.ts +21 -0
  13. package/dist/commands/hook/install.js +175 -0
  14. package/dist/commands/hook/paths.d.ts +19 -0
  15. package/dist/commands/hook/paths.js +94 -0
  16. package/dist/commands/hook/status.d.ts +7 -0
  17. package/dist/commands/hook/status.js +86 -0
  18. package/dist/commands/hook/uninstall.d.ts +8 -0
  19. package/dist/commands/hook/uninstall.js +71 -0
  20. package/dist/commands/hook-dispatch.d.ts +15 -0
  21. package/dist/commands/hook-dispatch.js +180 -0
  22. package/dist/commands/init.d.ts +24 -0
  23. package/dist/commands/init.js +133 -0
  24. package/dist/commands/kill.d.ts +12 -0
  25. package/dist/commands/kill.js +49 -0
  26. package/dist/commands/log.d.ts +13 -0
  27. package/dist/commands/log.js +97 -0
  28. package/dist/commands/parse-agent-message.d.ts +31 -0
  29. package/dist/commands/parse-agent-message.js +52 -0
  30. package/dist/commands/parse-common-flags.d.ts +36 -0
  31. package/dist/commands/parse-common-flags.js +105 -0
  32. package/dist/commands/ps.d.ts +12 -0
  33. package/dist/commands/ps.js +71 -0
  34. package/dist/commands/query.d.ts +21 -0
  35. package/dist/commands/query.js +117 -0
  36. package/dist/commands/result.d.ts +13 -0
  37. package/dist/commands/result.js +73 -0
  38. package/dist/commands/slack.d.ts +12 -0
  39. package/dist/commands/slack.js +559 -0
  40. package/dist/commands/task-db.d.ts +33 -0
  41. package/dist/commands/task-db.js +107 -0
  42. package/dist/examples/deny-secrets-plugin.d.ts +22 -0
  43. package/dist/examples/deny-secrets-plugin.js +40 -0
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +5 -0
  46. package/dist/logging.d.ts +21 -0
  47. package/dist/logging.js +86 -0
  48. package/dist/main.d.ts +10 -0
  49. package/dist/main.js +246 -256
  50. package/dist/plugins/examples/echo-hook.d.ts +24 -0
  51. package/dist/plugins/examples/echo-hook.js +60 -0
  52. package/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
  53. package/dist/plugins/examples/verify-echo-hook.js +47 -0
  54. package/dist/plugins/sqlite-tracing.d.ts +13 -0
  55. package/dist/plugins/sqlite-tracing.js +20 -0
  56. package/dist/register-builtin-tools.d.ts +5 -0
  57. package/dist/register-builtin-tools.js +9 -0
  58. package/dist/slack/file-download.d.ts +17 -0
  59. package/dist/slack/file-download.js +134 -0
  60. package/dist/slack/markdown.d.ts +5 -0
  61. package/dist/slack/markdown.js +33 -0
  62. package/dist/utils/env-defaults.d.ts +5 -0
  63. package/dist/utils/env-defaults.js +10 -0
  64. package/dist/utils/version.d.ts +1 -0
  65. package/dist/utils/version.js +28 -0
  66. package/package.json +32 -115
  67. package/README.md +0 -663
  68. package/dist/ai-provider.service.d.ts +0 -36
  69. package/dist/ai-provider.service.js +0 -315
  70. package/dist/ai-provider.service.js.map +0 -1
  71. package/dist/ai.service.d.ts +0 -17
  72. package/dist/ai.service.js +0 -51
  73. package/dist/ai.service.js.map +0 -1
  74. package/dist/app.module.d.ts +0 -5
  75. package/dist/app.module.js +0 -165
  76. package/dist/app.module.js.map +0 -1
  77. package/dist/cli/agent.handler.d.ts +0 -2
  78. package/dist/cli/agent.handler.js +0 -186
  79. package/dist/cli/agent.handler.js.map +0 -1
  80. package/dist/cli/builtin.handler.d.ts +0 -3
  81. package/dist/cli/builtin.handler.js.map +0 -1
  82. package/dist/cli/chat.handler.d.ts +0 -20
  83. package/dist/cli/chat.handler.js +0 -446
  84. package/dist/cli/chat.handler.js.map +0 -1
  85. package/dist/cli/cli.handler.d.ts +0 -4
  86. package/dist/cli/cli.handler.js +0 -119
  87. package/dist/cli/cli.handler.js.map +0 -1
  88. package/dist/cli/doctor.handler.d.ts +0 -38
  89. package/dist/cli/doctor.handler.js +0 -495
  90. package/dist/cli/doctor.handler.js.map +0 -1
  91. package/dist/cli/execute.handler.d.ts +0 -2
  92. package/dist/cli/execute.handler.js +0 -376
  93. package/dist/cli/execute.handler.js.map +0 -1
  94. package/dist/cli/help.handler.d.ts +0 -2
  95. package/dist/cli/help.handler.js +0 -10
  96. package/dist/cli/help.handler.js.map +0 -1
  97. package/dist/cli/init.handler.d.ts +0 -26
  98. package/dist/cli/init.handler.js +0 -450
  99. package/dist/cli/init.handler.js.map +0 -1
  100. package/dist/cli/log.handler.d.ts +0 -2
  101. package/dist/cli/log.handler.js +0 -69
  102. package/dist/cli/log.handler.js.map +0 -1
  103. package/dist/cli/mcp.handler.d.ts +0 -3
  104. package/dist/cli/mcp.handler.js +0 -121
  105. package/dist/cli/mcp.handler.js.map +0 -1
  106. package/dist/cli/query.handler.d.ts +0 -2
  107. package/dist/cli/query.handler.js +0 -392
  108. package/dist/cli/query.handler.js.map +0 -1
  109. package/dist/cli/skill.handler.d.ts +0 -2
  110. package/dist/cli/skill.handler.js +0 -252
  111. package/dist/cli/skill.handler.js.map +0 -1
  112. package/dist/cli/slack-files.handler.d.ts +0 -2
  113. package/dist/cli/slack-files.handler.js +0 -291
  114. package/dist/cli/slack-files.handler.js.map +0 -1
  115. package/dist/cli/template.handler.d.ts +0 -2
  116. package/dist/cli/template.handler.js +0 -188
  117. package/dist/cli/template.handler.js.map +0 -1
  118. package/dist/cli/templates.handler.d.ts +0 -2
  119. package/dist/cli/templates.handler.js +0 -100
  120. package/dist/cli/templates.handler.js.map +0 -1
  121. package/dist/cli-options.d.ts +0 -40
  122. package/dist/cli-options.js +0 -371
  123. package/dist/cli-options.js.map +0 -1
  124. package/dist/config/timeout.config.d.ts +0 -14
  125. package/dist/config/timeout.config.js +0 -34
  126. package/dist/config/timeout.config.js.map +0 -1
  127. package/dist/conversation/base-conversation-history.provider.d.ts +0 -12
  128. package/dist/conversation/base-conversation-history.provider.js +0 -45
  129. package/dist/conversation/base-conversation-history.provider.js.map +0 -1
  130. package/dist/conversation/cli-box-reader.adapter.d.ts +0 -6
  131. package/dist/conversation/cli-box-reader.adapter.js +0 -10
  132. package/dist/conversation/cli-box-reader.adapter.js.map +0 -1
  133. package/dist/conversation/cli-conversation-history.provider.d.ts +0 -16
  134. package/dist/conversation/cli-conversation-history.provider.js +0 -112
  135. package/dist/conversation/cli-conversation-history.provider.js.map +0 -1
  136. package/dist/conversation/cli-task-reader.adapter.d.ts +0 -6
  137. package/dist/conversation/cli-task-reader.adapter.js +0 -25
  138. package/dist/conversation/cli-task-reader.adapter.js.map +0 -1
  139. package/dist/conversation/conversation-provider.factory.d.ts +0 -10
  140. package/dist/conversation/conversation-provider.factory.js +0 -50
  141. package/dist/conversation/conversation-provider.factory.js.map +0 -1
  142. package/dist/conversation/index.d.ts +0 -8
  143. package/dist/conversation/index.js +0 -29
  144. package/dist/conversation/index.js.map +0 -1
  145. package/dist/conversation/slack-conversation-history.provider.d.ts +0 -29
  146. package/dist/conversation/slack-conversation-history.provider.js +0 -302
  147. package/dist/conversation/slack-conversation-history.provider.js.map +0 -1
  148. package/dist/crewx.tool.d.ts +0 -360
  149. package/dist/crewx.tool.js +0 -2531
  150. package/dist/crewx.tool.js.map +0 -1
  151. package/dist/crewx.tool.spec.d.ts +0 -1
  152. package/dist/crewx.tool.spec.js +0 -222
  153. package/dist/crewx.tool.spec.js.map +0 -1
  154. package/dist/guards/bearer-auth.guard.d.ts +0 -7
  155. package/dist/guards/bearer-auth.guard.js +0 -44
  156. package/dist/guards/bearer-auth.guard.js.map +0 -1
  157. package/dist/health.controller.d.ts +0 -6
  158. package/dist/health.controller.js +0 -32
  159. package/dist/health.controller.js.map +0 -1
  160. package/dist/main.js.map +0 -1
  161. package/dist/mcp.controller.d.ts +0 -8
  162. package/dist/mcp.controller.js +0 -62
  163. package/dist/mcp.controller.js.map +0 -1
  164. package/dist/package.json +0 -3
  165. package/dist/providers/dynamic-provider.factory.d.ts +0 -17
  166. package/dist/providers/dynamic-provider.factory.js +0 -138
  167. package/dist/providers/dynamic-provider.factory.js.map +0 -1
  168. package/dist/providers/logger.adapter.d.ts +0 -7
  169. package/dist/providers/logger.adapter.js +0 -107
  170. package/dist/providers/logger.adapter.js.map +0 -1
  171. package/dist/services/agent-loader.service.d.ts +0 -35
  172. package/dist/services/agent-loader.service.js +0 -623
  173. package/dist/services/agent-loader.service.js.map +0 -1
  174. package/dist/services/auth.service.d.ts +0 -9
  175. package/dist/services/auth.service.js +0 -47
  176. package/dist/services/auth.service.js.map +0 -1
  177. package/dist/services/config-validator.service.d.ts +0 -29
  178. package/dist/services/config-validator.service.js +0 -483
  179. package/dist/services/config-validator.service.js.map +0 -1
  180. package/dist/services/config.service.d.ts +0 -45
  181. package/dist/services/config.service.js +0 -352
  182. package/dist/services/config.service.js.map +0 -1
  183. package/dist/services/document-loader.service.d.ts +0 -26
  184. package/dist/services/document-loader.service.js +0 -186
  185. package/dist/services/document-loader.service.js.map +0 -1
  186. package/dist/services/help.service.d.ts +0 -5
  187. package/dist/services/help.service.js +0 -139
  188. package/dist/services/help.service.js.map +0 -1
  189. package/dist/services/intelligent-compression.service.d.ts +0 -20
  190. package/dist/services/intelligent-compression.service.js +0 -179
  191. package/dist/services/intelligent-compression.service.js.map +0 -1
  192. package/dist/services/mcp-client.service.d.ts +0 -26
  193. package/dist/services/mcp-client.service.js +0 -81
  194. package/dist/services/mcp-client.service.js.map +0 -1
  195. package/dist/services/parallel-processing.service.d.ts +0 -108
  196. package/dist/services/parallel-processing.service.js +0 -333
  197. package/dist/services/parallel-processing.service.js.map +0 -1
  198. package/dist/services/provider-bridge.service.d.ts +0 -35
  199. package/dist/services/provider-bridge.service.js +0 -224
  200. package/dist/services/provider-bridge.service.js.map +0 -1
  201. package/dist/services/remote-agent.service.d.ts +0 -50
  202. package/dist/services/remote-agent.service.js +0 -171
  203. package/dist/services/remote-agent.service.js.map +0 -1
  204. package/dist/services/result-formatter.service.d.ts +0 -27
  205. package/dist/services/result-formatter.service.js +0 -126
  206. package/dist/services/result-formatter.service.js.map +0 -1
  207. package/dist/services/skill-loader.service.d.ts +0 -15
  208. package/dist/services/skill-loader.service.js +0 -278
  209. package/dist/services/skill-loader.service.js.map +0 -1
  210. package/dist/services/skill.service.d.ts +0 -69
  211. package/dist/services/skill.service.js +0 -779
  212. package/dist/services/skill.service.js.map +0 -1
  213. package/dist/services/skill.service.spec.d.ts +0 -1
  214. package/dist/services/skill.service.spec.js +0 -168
  215. package/dist/services/skill.service.spec.js.map +0 -1
  216. package/dist/services/task-management.service.d.ts +0 -71
  217. package/dist/services/task-management.service.js +0 -324
  218. package/dist/services/task-management.service.js.map +0 -1
  219. package/dist/services/template.service.d.ts +0 -61
  220. package/dist/services/template.service.js +0 -416
  221. package/dist/services/template.service.js.map +0 -1
  222. package/dist/services/tool-call.service.d.ts +0 -16
  223. package/dist/services/tool-call.service.js +0 -302
  224. package/dist/services/tool-call.service.js.map +0 -1
  225. package/dist/services/tracing.service.d.ts +0 -197
  226. package/dist/services/tracing.service.js +0 -1267
  227. package/dist/services/tracing.service.js.map +0 -1
  228. package/dist/slack/formatters/message.formatter.d.ts +0 -43
  229. package/dist/slack/formatters/message.formatter.js +0 -505
  230. package/dist/slack/formatters/message.formatter.js.map +0 -1
  231. package/dist/slack/services/slack-file-download.service.d.ts +0 -58
  232. package/dist/slack/services/slack-file-download.service.js +0 -558
  233. package/dist/slack/services/slack-file-download.service.js.map +0 -1
  234. package/dist/slack/slack-bot.d.ts +0 -33
  235. package/dist/slack/slack-bot.js +0 -568
  236. package/dist/slack/slack-bot.js.map +0 -1
  237. package/dist/stderr.logger.d.ts +0 -8
  238. package/dist/stderr.logger.js +0 -26
  239. package/dist/stderr.logger.js.map +0 -1
  240. package/dist/types/usage.types.d.ts +0 -107
  241. package/dist/types/usage.types.js +0 -3
  242. package/dist/types/usage.types.js.map +0 -1
  243. package/dist/utils/config-utils.d.ts +0 -15
  244. package/dist/utils/config-utils.js +0 -69
  245. package/dist/utils/config-utils.js.map +0 -1
  246. package/dist/utils/extract-text.d.ts +0 -1
  247. package/dist/utils/extract-text.js +0 -15
  248. package/dist/utils/extract-text.js.map +0 -1
  249. package/dist/utils/mcp-installer.d.ts +0 -20
  250. package/dist/utils/mcp-installer.js +0 -199
  251. package/dist/utils/mcp-installer.js.map +0 -1
  252. package/dist/utils/project-hash.d.ts +0 -6
  253. package/dist/utils/project-hash.js +0 -70
  254. package/dist/utils/project-hash.js.map +0 -1
  255. package/dist/utils/simple-security.d.ts +0 -3
  256. package/dist/utils/simple-security.js +0 -20
  257. package/dist/utils/simple-security.js.map +0 -1
  258. package/dist/utils/stdin-utils.d.ts +0 -6
  259. package/dist/utils/stdin-utils.js +0 -109
  260. package/dist/utils/stdin-utils.js.map +0 -1
  261. package/dist/utils/template-processor.d.ts +0 -27
  262. package/dist/utils/template-processor.js +0 -395
  263. package/dist/utils/template-processor.js.map +0 -1
  264. package/dist/utils/terminal-message-formatter.d.ts +0 -23
  265. package/dist/utils/terminal-message-formatter.js +0 -136
  266. package/dist/utils/terminal-message-formatter.js.map +0 -1
  267. package/dist/version.d.ts +0 -1
  268. package/dist/version.js +0 -17
  269. package/dist/version.js.map +0 -1
  270. package/dist/workspace.service.d.ts +0 -44
  271. package/dist/workspace.service.js +0 -299
  272. package/dist/workspace.service.js.map +0 -1
  273. package/scripts/backfill-tokens.js +0 -218
  274. package/scripts/postbuild-cli.mjs +0 -88
  275. package/scripts/postinstall-cli.mjs +0 -30
  276. package/templates/agents/default.yaml +0 -490
  277. package/templates/agents/minimal.yaml +0 -16
  278. package/templates/documents/conversation-history-default.hbs +0 -17
  279. package/templates/documents/crewx-manual.md +0 -2278
  280. package/templates/documents/crewx-quick-guide.md +0 -147
  281. 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>;