Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/developers/sdk-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Creates a new query session with the Qwen Code.
| `permissionMode` | `'default' \| 'plan' \| 'auto-edit' \| 'yolo'` | `'default'` | Permission mode controlling tool execution approval. See [Permission Modes](#permission-modes) for details. |
| `canUseTool` | `CanUseTool` | - | Custom permission handler for tool execution approval. Invoked when a tool requires confirmation. Must respond within 60 seconds or the request will be auto-denied. See [Custom Permission Handler](#custom-permission-handler). |
| `env` | `Record<string, string>` | - | Environment variables to pass to the Qwen Code process. Merged with the current process environment. |
| `systemPrompt` | `string \| QuerySystemPromptPreset` | - | System prompt configuration for the main session. Use a string to fully override the built-in Qwen Code system prompt, or a preset object to keep the built-in prompt and append extra instructions. |
| `mcpServers` | `Record<string, McpServerConfig>` | - | MCP (Model Context Protocol) servers to connect. Supports external servers (stdio/SSE/HTTP) and SDK-embedded servers. External servers are configured with transport options like `command`, `args`, `url`, `httpUrl`, etc. SDK servers use `{ type: 'sdk', name: string, instance: Server }`. |
| `abortController` | `AbortController` | - | Controller to cancel the query session. Call `abortController.abort()` to terminate the session and cleanup resources. |
| `debug` | `boolean` | `false` | Enable debug mode for verbose logging from the CLI process. |
Expand Down Expand Up @@ -248,6 +249,36 @@ const result = query({
});
```

### Override the System Prompt

```typescript
import { query } from '@qwen-code/sdk';

const result = query({
prompt: 'Say hello in one sentence.',
options: {
systemPrompt: 'You are a terse assistant. Answer in exactly one sentence.',
},
});
```

### Append to the Built-in System Prompt

```typescript
import { query } from '@qwen-code/sdk';

const result = query({
prompt: 'Review the current directory.',
options: {
systemPrompt: {
type: 'preset',
preset: 'qwen_code',
append: 'Be terse and focus on concrete findings.',
},
},
});
```

### With SDK-Embedded MCP Servers

The SDK provides `tool` and `createSdkMcpServer` to create MCP servers that run in the same process as your SDK application. This is useful when you want to expose custom tools to the AI without running a separate server process.
Expand Down
2 changes: 2 additions & 0 deletions docs/users/configuration/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ Arguments passed directly when running the CLI can override other configurations
| `--model` | `-m` | Specifies the Qwen model to use for this session. | Model name | Example: `npm start -- --model qwen3-coder-plus` |
| `--prompt` | `-p` | Used to pass a prompt directly to the command. This invokes Qwen Code in a non-interactive mode. | Your prompt text | For scripting examples, use the `--output-format json` flag to get structured output. |
| `--prompt-interactive` | `-i` | Starts an interactive session with the provided prompt as the initial input. | Your prompt text | The prompt is processed within the interactive session, not before it. Cannot be used when piping input from stdin. Example: `qwen -i "explain this code"` |
| `--system-prompt` | | Overrides the built-in main session system prompt for this run. | Your prompt text | Loaded context files such as `QWEN.md` are still appended after this override. Can be combined with `--append-system-prompt`. |
| `--append-system-prompt` | | Appends extra instructions to the main session system prompt for this run. | Your prompt text | Applied after the built-in prompt and loaded context files. Can be combined with `--system-prompt`. See [Headless Mode](../features/headless) for examples. |
| `--output-format` | `-o` | Specifies the format of the CLI output for non-interactive mode. | `text`, `json`, `stream-json` | `text`: (Default) The standard human-readable output. `json`: A machine-readable JSON output emitted at the end of execution. `stream-json`: Streaming JSON messages emitted as they occur during execution. For structured output and scripting, use the `--output-format json` or `--output-format stream-json` flag. See [Headless Mode](../features/headless) for detailed information. |
| `--input-format` | | Specifies the format consumed from standard input. | `text`, `stream-json` | `text`: (Default) Standard text input from stdin or command-line arguments. `stream-json`: JSON message protocol via stdin for bidirectional communication. Requirement: `--input-format stream-json` requires `--output-format stream-json` to be set. When using `stream-json`, stdin is reserved for protocol messages. See [Headless Mode](../features/headless) for detailed information. |
| `--include-partial-messages` | | Include partial assistant messages when using `stream-json` output format. When enabled, emits stream events (message_start, content_block_delta, etc.) as they occur during streaming. | | Default: `false`. Requirement: Requires `--output-format stream-json` to be set. See [Headless Mode](../features/headless) for detailed information about stream events. |
Expand Down
62 changes: 49 additions & 13 deletions docs/users/features/headless.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,40 @@ qwen --resume 123e4567-e89b-12d3-a456-426614174000 -p "Apply the follow-up refac
> - Session data is project-scoped JSONL under `~/.qwen/projects/<sanitized-cwd>/chats`.
> - Restores conversation history, tool outputs, and chat-compression checkpoints before sending the new prompt.

## Customize the Main Session Prompt

You can change the main session system prompt for a single CLI run without editing shared memory files.

### Override the Built-in System Prompt

Use `--system-prompt` to replace Qwen Code's built-in main-session prompt for the current run:

```bash
qwen -p "Review this patch" --system-prompt "You are a terse release reviewer. Report only blocking issues."
```

### Append Extra Instructions

Use `--append-system-prompt` to keep the built-in prompt and add extra instructions for this run:

```bash
qwen -p "Review this patch" --append-system-prompt "Be terse and focus on concrete findings."
```

You can combine both flags when you want a custom base prompt plus an extra run-specific instruction:

```bash
qwen -p "Summarize this repository" \
--system-prompt "You are a migration planner." \
--append-system-prompt "Return exactly three bullets."
```

> [!note]
>
> - `--system-prompt` applies only to the current run's main session.
> - Loaded memory and context files such as `QWEN.md` are still appended after `--system-prompt`.
> - `--append-system-prompt` is applied after the built-in prompt and loaded memory, and can be used together with `--system-prompt`.

## Output Formats

Qwen Code supports multiple output formats for different use cases:
Expand Down Expand Up @@ -189,19 +223,21 @@ qwen -p "Write code" --output-format stream-json --include-partial-messages | jq

Key command-line options for headless usage:

| Option | Description | Example |
| ---------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------ |
| `--prompt`, `-p` | Run in headless mode | `qwen -p "query"` |
| `--output-format`, `-o` | Specify output format (text, json, stream-json) | `qwen -p "query" --output-format json` |
| `--input-format` | Specify input format (text, stream-json) | `qwen --input-format text --output-format stream-json` |
| `--include-partial-messages` | Include partial messages in stream-json output | `qwen -p "query" --output-format stream-json --include-partial-messages` |
| `--debug`, `-d` | Enable debug mode | `qwen -p "query" --debug` |
| `--all-files`, `-a` | Include all files in context | `qwen -p "query" --all-files` |
| `--include-directories` | Include additional directories | `qwen -p "query" --include-directories src,docs` |
| `--yolo`, `-y` | Auto-approve all actions | `qwen -p "query" --yolo` |
| `--approval-mode` | Set approval mode | `qwen -p "query" --approval-mode auto_edit` |
| `--continue` | Resume the most recent session for this project | `qwen --continue -p "Pick up where we left off"` |
| `--resume [sessionId]` | Resume a specific session (or choose interactively) | `qwen --resume 123e... -p "Finish the refactor"` |
| Option | Description | Example |
| ---------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `--prompt`, `-p` | Run in headless mode | `qwen -p "query"` |
| `--output-format`, `-o` | Specify output format (text, json, stream-json) | `qwen -p "query" --output-format json` |
| `--input-format` | Specify input format (text, stream-json) | `qwen --input-format text --output-format stream-json` |
| `--include-partial-messages` | Include partial messages in stream-json output | `qwen -p "query" --output-format stream-json --include-partial-messages` |
| `--system-prompt` | Override the main session system prompt for this run | `qwen -p "query" --system-prompt "You are a terse reviewer."` |
| `--append-system-prompt` | Append extra instructions to the main session system prompt for this run | `qwen -p "query" --append-system-prompt "Focus on concrete findings."` |
| `--debug`, `-d` | Enable debug mode | `qwen -p "query" --debug` |
| `--all-files`, `-a` | Include all files in context | `qwen -p "query" --all-files` |
| `--include-directories` | Include additional directories | `qwen -p "query" --include-directories src,docs` |
| `--yolo`, `-y` | Auto-approve all actions | `qwen -p "query" --yolo` |
| `--approval-mode` | Set approval mode | `qwen -p "query" --approval-mode auto_edit` |
| `--continue` | Resume the most recent session for this project | `qwen --continue -p "Pick up where we left off"` |
| `--resume [sessionId]` | Resume a specific session (or choose interactively) | `qwen --resume 123e... -p "Finish the refactor"` |

For complete details on all available configuration options, settings files, and environment variables, see the [Configuration Guide](../configuration/settings).

Expand Down
39 changes: 39 additions & 0 deletions packages/cli/src/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,30 @@ describe('parseArguments', () => {
expect(argv.prompt).toBeUndefined();
});

it('should parse --system-prompt', async () => {
process.argv = [
'node',
'script.js',
'--system-prompt',
'You are a test system prompt.',
];
const argv = await parseArguments();
expect(argv.systemPrompt).toBe('You are a test system prompt.');
expect(argv.appendSystemPrompt).toBeUndefined();
});

it('should parse --append-system-prompt', async () => {
process.argv = [
'node',
'script.js',
'--append-system-prompt',
'Be extra concise.',
];
const argv = await parseArguments();
expect(argv.appendSystemPrompt).toBe('Be extra concise.');
expect(argv.systemPrompt).toBeUndefined();
});

it('should allow -r flag as alias for --resume', async () => {
process.argv = [
'node',
Expand Down Expand Up @@ -432,6 +456,21 @@ describe('parseArguments', () => {
mockExit.mockRestore();
});

it('should allow --system-prompt and --append-system-prompt together', async () => {
process.argv = [
'node',
'script.js',
'--system-prompt',
'Override prompt',
'--append-system-prompt',
'Append prompt',
];

const argv = await parseArguments();
expect(argv.systemPrompt).toBe('Override prompt');
expect(argv.appendSystemPrompt).toBe('Append prompt');
});

it('should throw an error when include-partial-messages is used without stream-json output', async () => {
process.argv = ['node', 'script.js', '--include-partial-messages'];

Expand Down
Loading
Loading