@crewx/cli 0.8.1-rc.1 → 0.8.1-rc.3

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.
@@ -11,6 +11,12 @@
11
11
  * --config/-c <path> Config file path override
12
12
  * --output-format <fmt> Output format (json|text|stream-json)
13
13
  * --effort <level> Model effort (high|medium|low)
14
+ * -f/--prompt-file <path> Read task body from file (bypasses cmd.exe argv truncation)
15
+ *
16
+ * Stdin support:
17
+ * Pipe or redirect content into crewx x to supply the task body via stdin.
18
+ * e.g. cat task.md | crewx x "@agent label"
19
+ * Stdin is ignored when running in an interactive TTY.
14
20
  */
15
21
  /**
16
22
  * Handle `crewx execute <agentRef> <message>` command.
@@ -12,12 +12,19 @@
12
12
  * --config/-c <path> Config file path override
13
13
  * --output-format <fmt> Output format (json|text|stream-json)
14
14
  * --effort <level> Model effort (high|medium|low)
15
+ * -f/--prompt-file <path> Read task body from file (bypasses cmd.exe argv truncation)
16
+ *
17
+ * Stdin support:
18
+ * Pipe or redirect content into crewx x to supply the task body via stdin.
19
+ * e.g. cat task.md | crewx x "@agent label"
20
+ * Stdin is ignored when running in an interactive TTY.
15
21
  */
16
22
  Object.defineProperty(exports, "__esModule", { value: true });
17
23
  exports.handleExecute = handleExecute;
18
24
  const sdk_1 = require("@crewx/sdk");
19
25
  const parse_agent_message_1 = require("./parse-agent-message");
20
26
  const parse_common_flags_1 = require("./parse-common-flags");
27
+ const resolve_prompt_1 = require("./resolve-prompt");
21
28
  const crewx_cli_1 = require("../bootstrap/crewx-cli");
22
29
  /**
23
30
  * Handle `crewx execute <agentRef> <message>` command.
@@ -26,27 +33,36 @@ const crewx_cli_1 = require("../bootstrap/crewx-cli");
26
33
  * --verbose: debug info written to stderr, response to stdout.
27
34
  */
28
35
  async function handleExecute(args) {
29
- const { thread, provider, metadata, verbose, config, outputFormat, effort, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
36
+ const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
30
37
  const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
31
38
  // No @mention → default to @crewx agent (matches cli-bak behaviour)
32
39
  const agentRef = parsedAgentRef || '@crewx';
33
- if (!message) {
40
+ // Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
41
+ const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
42
+ if (!finalMessage) {
34
43
  console.error('Usage: crewx execute [@agent] <task> [options]');
35
44
  console.error(' crewx x [@agent] <task> [options]');
36
45
  console.error('');
37
46
  console.error(' @agent is optional. Defaults to @crewx when omitted.');
47
+ console.error(' Task body can also be supplied via stdin pipe or --prompt-file.');
48
+ console.error('');
49
+ console.error('Examples:');
50
+ console.error(' crewx x "@agent do something"');
51
+ console.error(' cat task.md | crewx x "@agent label"');
52
+ console.error(' crewx x "@agent label" --prompt-file=task.md');
38
53
  console.error('');
39
54
  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)');
55
+ console.error(' --thread <name> Conversation thread name');
56
+ console.error(' --provider <cli/xxx> Provider override');
57
+ console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
58
+ console.error(' Propagated to events/hooks/tracing.');
59
+ console.error(' Invalid JSON aborts with exit code 2.');
60
+ console.error(' e.g. --metadata=\'{"workflow_id":"wf-1"}\'');
61
+ console.error(' --verbose Debug output mode');
62
+ console.error(' --config/-c <path> Config file path');
63
+ console.error(' --output-format <fmt> Output format (json|text|stream-json)');
64
+ console.error(' --effort <level> Model effort (high|medium|low)');
65
+ console.error(' -f/--prompt-file <path> Read task body from file');
50
66
  process.exit(1);
51
67
  }
52
68
  const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
@@ -55,7 +71,7 @@ async function handleExecute(args) {
55
71
  const crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
56
72
  // file:// remote agent delegation is handled transparently inside Crewx.query/execute.
57
73
  if (verbose) {
58
- process.stderr.write(`📋 Task: ${message}\n`);
74
+ process.stderr.write(`📋 Task: ${finalMessage}\n`);
59
75
  process.stderr.write(`🤖 Agent: ${agentRef}\n`);
60
76
  if (thread)
61
77
  process.stderr.write(`🔗 Thread: ${thread}\n`);
@@ -78,7 +94,7 @@ async function handleExecute(args) {
78
94
  }
79
95
  let exitCode = 0;
80
96
  try {
81
- const result = await crewx.execute(agentRef, message, {
97
+ const result = await crewx.execute(agentRef, finalMessage, {
82
98
  provider,
83
99
  threadId: thread,
84
100
  metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
@@ -20,6 +20,8 @@ export interface CommonFlags {
20
20
  outputFormat?: string;
21
21
  /** Model effort level (high | medium | low). */
22
22
  effort?: string;
23
+ /** Path to a file whose content is used as the prompt body (-f/--prompt-file). */
24
+ promptFile?: string;
23
25
  /** Remaining non-flag arguments. */
24
26
  rest: string[];
25
27
  }
@@ -46,6 +46,7 @@ function parseCommonFlags(args) {
46
46
  const config = parseFlag(args, '--config', '-c');
47
47
  const outputFormat = parseFlag(args, '--output-format');
48
48
  const effort = parseFlag(args, '--effort');
49
+ const promptFile = parseFlag(args, '--prompt-file', '-f');
49
50
  const verbose = hasFlag(args, '--verbose');
50
51
  // Collect the set of consumed positions
51
52
  const consumed = new Set();
@@ -56,6 +57,7 @@ function parseCommonFlags(args) {
56
57
  { names: ['--config', '-c'] },
57
58
  { names: ['--output-format'] },
58
59
  { names: ['--effort'] },
60
+ { names: ['--prompt-file', '-f'] },
59
61
  ];
60
62
  for (let i = 0; i < args.length; i++) {
61
63
  const arg = args[i];
@@ -79,7 +81,7 @@ function parseCommonFlags(args) {
79
81
  }
80
82
  }
81
83
  const rest = args.filter((_, i) => !consumed.has(i));
82
- return { thread, provider, metadata, verbose, config, outputFormat, effort, rest };
84
+ return { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, rest };
83
85
  }
84
86
  /**
85
87
  * Parse metadata JSON string from --metadata flag.
@@ -11,6 +11,12 @@
11
11
  * --config/-c <path> Config file path override
12
12
  * --output-format <fmt> Output format (json|text|stream-json)
13
13
  * --effort <level> Model effort (high|medium|low)
14
+ * -f/--prompt-file <path> Read prompt body from file (bypasses cmd.exe argv truncation)
15
+ *
16
+ * Stdin support:
17
+ * Pipe or redirect content into crewx q to supply the prompt body via stdin.
18
+ * e.g. cat brief.md | crewx q "@agent label"
19
+ * Stdin is ignored when running in an interactive TTY.
14
20
  */
15
21
  /**
16
22
  * Handle `crewx query <agentRef> <message>` command.
@@ -12,12 +12,19 @@
12
12
  * --config/-c <path> Config file path override
13
13
  * --output-format <fmt> Output format (json|text|stream-json)
14
14
  * --effort <level> Model effort (high|medium|low)
15
+ * -f/--prompt-file <path> Read prompt body from file (bypasses cmd.exe argv truncation)
16
+ *
17
+ * Stdin support:
18
+ * Pipe or redirect content into crewx q to supply the prompt body via stdin.
19
+ * e.g. cat brief.md | crewx q "@agent label"
20
+ * Stdin is ignored when running in an interactive TTY.
15
21
  */
16
22
  Object.defineProperty(exports, "__esModule", { value: true });
17
23
  exports.handleQuery = handleQuery;
18
24
  const sdk_1 = require("@crewx/sdk");
19
25
  const parse_agent_message_1 = require("./parse-agent-message");
20
26
  const parse_common_flags_1 = require("./parse-common-flags");
27
+ const resolve_prompt_1 = require("./resolve-prompt");
21
28
  const crewx_cli_1 = require("../bootstrap/crewx-cli");
22
29
  /**
23
30
  * Handle `crewx query <agentRef> <message>` command.
@@ -26,27 +33,36 @@ const crewx_cli_1 = require("../bootstrap/crewx-cli");
26
33
  * --verbose: debug info written to stderr, response to stdout.
27
34
  */
28
35
  async function handleQuery(args) {
29
- const { thread, provider, metadata, verbose, config, outputFormat, effort, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
36
+ const { thread, provider, metadata, verbose, config, outputFormat, effort, promptFile, rest } = (0, parse_common_flags_1.parseCommonFlags)(args);
30
37
  const { agentRef: parsedAgentRef, message } = (0, parse_agent_message_1.parseAgentMessage)(rest);
31
38
  // No @mention → default to @crewx agent (matches cli-bak behaviour)
32
39
  const agentRef = parsedAgentRef || '@crewx';
33
- if (!message) {
40
+ // Resolve final prompt: argv | stdin pipe | --prompt-file (or combination)
41
+ const finalMessage = await (0, resolve_prompt_1.resolvePrompt)(message, promptFile);
42
+ if (!finalMessage) {
34
43
  console.error('Usage: crewx query [@agent] <message> [options]');
35
44
  console.error(' crewx q [@agent] <message> [options]');
36
45
  console.error('');
37
46
  console.error(' @agent is optional. Defaults to @crewx when omitted.');
47
+ console.error(' Prompt can also be supplied via stdin pipe or --prompt-file.');
48
+ console.error('');
49
+ console.error('Examples:');
50
+ console.error(' crewx q "@agent hello"');
51
+ console.error(' cat brief.md | crewx q "@agent summarise"');
52
+ console.error(' crewx q "@agent label" --prompt-file=brief.md');
38
53
  console.error('');
39
54
  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)');
55
+ console.error(' --thread <name> Conversation thread name');
56
+ console.error(' --provider <cli/xxx> Provider override');
57
+ console.error(' --metadata <json> Extra metadata (JSON object, double-quoted).');
58
+ console.error(' Propagated to events/hooks/tracing.');
59
+ console.error(' Invalid JSON aborts with exit code 2.');
60
+ console.error(' e.g. --metadata=\'{"workflow_id":"wf-1"}\'');
61
+ console.error(' --verbose Debug output mode');
62
+ console.error(' --config/-c <path> Config file path');
63
+ console.error(' --output-format <fmt> Output format (json|text|stream-json)');
64
+ console.error(' --effort <level> Model effort (high|medium|low)');
65
+ console.error(' -f/--prompt-file <path> Read prompt body from file');
50
66
  process.exit(1);
51
67
  }
52
68
  const configPath = config ?? process.env.CREWX_CONFIG ?? 'crewx.yaml';
@@ -55,7 +71,7 @@ async function handleQuery(args) {
55
71
  const crewx = await (0, crewx_cli_1.createCliCrewx)(configPath);
56
72
  // file:// remote agent delegation is handled transparently inside Crewx.query/execute.
57
73
  if (verbose) {
58
- process.stderr.write(`📋 Task: ${message}\n`);
74
+ process.stderr.write(`📋 Task: ${finalMessage}\n`);
59
75
  process.stderr.write(`🤖 Agent: ${agentRef}\n`);
60
76
  if (thread)
61
77
  process.stderr.write(`🔗 Thread: ${thread}\n`);
@@ -78,7 +94,7 @@ async function handleQuery(args) {
78
94
  }
79
95
  let exitCode = 0;
80
96
  try {
81
- const result = await crewx.query(agentRef, message, {
97
+ const result = await crewx.query(agentRef, finalMessage, {
82
98
  provider,
83
99
  threadId: thread,
84
100
  metadata: Object.keys(parsedMetadata).length > 0 ? parsedMetadata : undefined,
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Prompt resolution utilities for q/x commands.
3
+ *
4
+ * Supports three input channels:
5
+ * 1. --prompt-file <path> — read content from a file
6
+ * 2. stdin pipe/redirect — read from process.stdin when not a TTY
7
+ * 3. argv prompt — positional argument passed directly on the command line
8
+ *
9
+ * When multiple sources are present, argv is used as a short label/prefix
10
+ * and the file/stdin content is appended after a blank line.
11
+ */
12
+ /**
13
+ * Read all bytes from stdin (pipe or redirect).
14
+ * Returns empty string when stdin is a TTY (interactive terminal).
15
+ */
16
+ export declare function readStdin(): Promise<string>;
17
+ /**
18
+ * Resolve the final prompt from argv, stdin pipe, or --prompt-file.
19
+ *
20
+ * Priority:
21
+ * 1. promptFile is specified → read file content (ignores stdin)
22
+ * 2. stdin pipe/redirect → read stdin
23
+ * 3. argv + external both present → `${argv}\n\n${external}`
24
+ * 4. Only one source present → use that source alone
25
+ * 5. Neither present → return '' (caller decides error handling)
26
+ *
27
+ * @param _readStdin - injectable stdin reader, defaults to the module-level
28
+ * readStdin. Exposed as a parameter so unit tests can substitute a stub
29
+ * without fighting ESM module binding rules.
30
+ */
31
+ export declare function resolvePrompt(argvPrompt: string, promptFile?: string, _readStdin?: () => Promise<string>): Promise<string>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Prompt resolution utilities for q/x commands.
4
+ *
5
+ * Supports three input channels:
6
+ * 1. --prompt-file <path> — read content from a file
7
+ * 2. stdin pipe/redirect — read from process.stdin when not a TTY
8
+ * 3. argv prompt — positional argument passed directly on the command line
9
+ *
10
+ * When multiple sources are present, argv is used as a short label/prefix
11
+ * and the file/stdin content is appended after a blank line.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.readStdin = readStdin;
15
+ exports.resolvePrompt = resolvePrompt;
16
+ const fs_1 = require("fs");
17
+ /**
18
+ * Read all bytes from stdin (pipe or redirect).
19
+ * Returns empty string when stdin is a TTY (interactive terminal).
20
+ */
21
+ async function readStdin() {
22
+ if (process.stdin.isTTY)
23
+ return '';
24
+ const chunks = [];
25
+ for await (const chunk of process.stdin)
26
+ chunks.push(chunk);
27
+ return Buffer.concat(chunks).toString('utf8').trimEnd();
28
+ }
29
+ /**
30
+ * Resolve the final prompt from argv, stdin pipe, or --prompt-file.
31
+ *
32
+ * Priority:
33
+ * 1. promptFile is specified → read file content (ignores stdin)
34
+ * 2. stdin pipe/redirect → read stdin
35
+ * 3. argv + external both present → `${argv}\n\n${external}`
36
+ * 4. Only one source present → use that source alone
37
+ * 5. Neither present → return '' (caller decides error handling)
38
+ *
39
+ * @param _readStdin - injectable stdin reader, defaults to the module-level
40
+ * readStdin. Exposed as a parameter so unit tests can substitute a stub
41
+ * without fighting ESM module binding rules.
42
+ */
43
+ async function resolvePrompt(argvPrompt, promptFile, _readStdin = readStdin) {
44
+ let external = '';
45
+ if (promptFile) {
46
+ external = (0, fs_1.readFileSync)(promptFile, 'utf8').trimEnd();
47
+ }
48
+ else {
49
+ external = (await _readStdin()).trimEnd();
50
+ }
51
+ if (argvPrompt && external)
52
+ return `${argvPrompt}\n\n${external}`;
53
+ return external || argvPrompt;
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewx/cli",
3
- "version": "0.8.1-rc.1",
3
+ "version": "0.8.1-rc.3",
4
4
  "license": "UNLICENSED",
5
5
  "engines": {
6
6
  "node": ">=20.19.0"
@@ -28,13 +28,13 @@
28
28
  "@crewx/adapter-slack": "0.1.3",
29
29
  "better-sqlite3": "*",
30
30
  "@crewx/memory": "0.1.9",
31
+ "@crewx/search": "0.1.8",
31
32
  "@crewx/wbs": "0.1.8",
32
- "@crewx/sdk": "0.8.1-rc.1",
33
- "@crewx/cron": "0.1.7",
34
33
  "@crewx/doc": "0.1.7",
35
- "@crewx/search": "0.1.8",
34
+ "@crewx/sdk": "0.8.1-rc.3",
36
35
  "@crewx/workflow": "0.3.7",
37
36
  "@crewx/skill": "0.1.6",
37
+ "@crewx/cron": "0.1.7",
38
38
  "@crewx/shared": "0.0.4"
39
39
  },
40
40
  "devDependencies": {