- glob: compute relativePaths relative to projectRoot (config.getTargetDir())
instead of searchDir so that FileDiscoveryService evaluates .gitignore /
.qwenignore rules against the correct paths when path option is used or
when searching across multiple workspace directories
- grep: deduplicate rawMatches by filePath:lineNumber key when searching
multiple workspace directories to prevent duplicate results from
overlapping search roots (e.g. parent dir + child dir in workspace)
- ripGrep: deduplicate output lines by filepath:linenum prefix when
searching multiple workspace paths to handle the same edge case
- tests: add regression tests covering
- glob ignores files matching .gitignore/.qwenignore when path option
points to a subdirectory
- grep deduplication with parent+child overlapping workspace dirs
- ripgrep deduplication when raw output contains duplicate lines
- Add comprehensive DingTalk setup guide with prerequisites, configuration, and troubleshooting
- Add WeChat and DingTalk entries to channels navigation
This provides users with complete documentation for setting up and using DingTalk as a Qwen Code channel.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add interfaces for DingTalkRepliedMsg and DingTalkRichTextPart types
- Support both newer text.repliedMsg and legacy quoteMessage formats
- Extract quoted message context with isReplyToBot detection
- Summarize replied content (text, richText, media placeholders)
This enables the bot to understand when users are replying to specific
messages and provides context about what message is being referenced.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Handle richText, picture, file, audio, video message types
- Download media via DingTalk API two-step flow
- Attach images as base64, save other files to temp dir
- Add DingTalkMessageData interface for richer payloads
This enables the DingTalk channel to process media attachments
in incoming messages.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Convert tables to pipe-separated plain text (DingTalk doesn't render tables)
- Split long messages into chunks respecting ~3800 char limit
- Handle code fences across chunk boundaries
- Extract title from first markdown line for webhook payload
This ensures markdown content renders correctly in DingTalk's limited renderer.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Cache sessionWebhook by conversationId for reliable message routing
- Show 👀 reaction while processing messages, then recall it
- Use conversationId as chatId instead of webhook URL
- Fix rawData parsing for already-parsed message data
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add @qwen-code/channel-dingtalk package with stream-based bot integration
- Support clientId/clientSecret authentication for DingTalk
- Add message deduplication and group chat mention handling
- Update ChannelConfig type to include dingtalk channel type
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
In ACP mode (e.g., Zed editor), process.cwd() may return '/' (filesystem root),
causing OpenAILogger to attempt creating '/logs/openai' which fails with ENOENT.
Add an optional 'cwd' parameter to OpenAILogger constructor and pass
config.getWorkingDir() from LoggingContentGenerator so that log directories
are resolved relative to the project working directory instead of process.cwd().
Fixes#2671
- Add referencedText field to Envelope for quoted/replied-to messages
- TelegramAdapter extracts text from reply_to_message
- WeixinAdapter extracts text from ref_msg field
- ChannelBase prepends referenced text to agent prompt
This allows the agent to see what message a user is replying to,
providing better context for conversations in both Telegram and WeChat.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add /help, /clear (aliases: /reset, /new), /status commands to ChannelBase
- Commands are handled locally without agent round-trip
- TelegramAdapter skips "Working..." indicator for local commands
- Update docs to reflect new command structure
This provides a consistent command interface across all channel types
(Telegram, WeChat, etc.) with platform-specific extensibility.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add `qwen channel status` to check running service info
- Add `qwen channel stop` to gracefully stop the service
- Add PID file tracking to prevent duplicate service instances
- Update documentation with new commands and usage
This enables users to manage the channel service from another terminal
without needing to use Ctrl+C on the foreground process.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add session persistence to SessionRouter for crash recovery
- Add loadSession method to AcpBridge for restoring sessions
- Add ChannelBaseOptions to support external router injection
- Refactor start.ts to support both standalone and gateway modes
- Extract config utilities into separate module
This enables channels to recover sessions after bridge crashes and
supports running multiple channels under a gateway process.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add connectWithRetry() method with exponential backoff (3 retries max)
- Add cleanupForRetry() to clean partial state between retry attempts
- Improve readiness detection with proper timeout and exit handling
- Add timeout for ACP initialize handshake (15s)
- Add auto-reconnect on unexpected subprocess exit (max 1 attempt)
- Track intentionalDisconnect flag to skip auto-reconnect for user-initiated disconnects
- Add onAutoReconnectFailed callback for user notification when auto-reconnect fails
- Show VS Code warning notification with 'Retry Connection' action button
- Add comprehensive tests for retry logic, cleanup, and intentional disconnect flag
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
The panel onDidDispose and webviewView onDidDispose callbacks were not
calling agentManager.disconnect(), so closing a chat tab or sidebar
view left the CLI child process running as an orphan. Only the
WebViewProvider.dispose() method (called on extension deactivation)
had the disconnect call.
Add agentManager.disconnect() to both dispose callbacks so the CLI
process receives SIGTERM when the user closes the tab.
PR #2472 added SIGTERM/SIGINT handlers in runAcpAgent() that destroy
stdin/stdout streams, allowing the ACP connection to close. However,
it did not call runExitCleanup() to terminate child processes (MCP
servers, etc.) spawned by the CLI. This caused orphan subprocesses
to persist after the IDE disconnects, especially noticeable in VSCode
with multiple tabs.
Changes:
- acpAgent.ts: Call runExitCleanup() in the shutdown signal handler
before process.exit(0), ensuring MCP server subprocesses are killed
- gemini.tsx: Call runExitCleanup() + process.exit(0) after
runAcpAgent() returns normally, matching the cleanup pattern used
by other non-interactive exit paths
- Add 4 unit tests covering SIGTERM cleanup, SIGINT cleanup,
idempotent shutdown, and cleanup-failure resilience
Closes#1884
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add Media Support section to overview with images and files
- Document model option for multimodal channel support
- Add Images and Files section to Telegram guide
- Add complete WeChat (Weixin) setup guide with QR auth
This documents the new media handling capabilities added to both Telegram and WeChat channels.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add photo message handling in Telegram adapter with base64 encoding
- Add document/file message handling with temp directory storage
- Extend WeChat adapter to support file downloads from CDN
- Refactor envelope building into reusable buildEnvelope method
- Rename ImageCdnRef to CdnRef for generic media handling
This enables users to send images and files through both Telegram and WeChat channels, with files saved to a temp directory for agent access.
- Add model configuration option for channel-specific model selection
- Support base64-encoded images in prompts via AcpBridge
- Add media utilities for WeChat/Weixin channel
- Update settings schema for model configuration
Enables channels to process images and use custom models.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
When conversation history is near the context window limit and dominated by
tool call/response cycles, findCompressSplitPoint would return a near-zero
split point because it only considered non-functionResponse user messages as
valid split points. This caused /compress to send almost no history to the
compression API (e.g. 29 tokens), producing a useless summary that inflated
token count instead of reducing it.
Changes:
- Track tool completion boundaries (positions after functionResponse) as
fallback split points in findCompressSplitPoint
- Add user-with-functionResponse to the compress-everything safety check
- Use Math.max of primary and fallback split points for better coverage
- Add minimum content guard (5% threshold) to prevent futile API calls
- Add 4 new test cases covering tool-heavy conversation scenarios
Fixes#2647
- Make hook events fire-and-forget in clearCommand to avoid blocking UI
- Move context.ui.clear() before resetChat for immediate responsiveness
- Add hasHooksForEvent() fast-path check to HookSystem and Config
- Skip MessageBus round-trips in client.ts when no hooks are registered
- Add comprehensive unit tests for all changes
Fixes#2651
- Add GroupGate class for group access control with three policies:
disabled (default), allowlist, and open
- Implement mention gating: bot only responds when @mentioned or replied to
in groups (configurable per-group)
- Extend Envelope type with isGroup, isMentioned, isReplyToBot fields
- Update TelegramAdapter to detect group context and mentions
- Add comprehensive documentation for group chat setup and troubleshooting
This enables using Qwen Code bots in Telegram groups with fine-grained
access control and mention-based activation to prevent noise.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
The trust/isTrustedFolder logic was accidentally dropped during the
permission system refactor in feat/support-permission (PR #2283).
Previously, shouldConfirmExecute() returned false (no confirmation) when
both conditions were met:
- MCP server config has trust: true
- The workspace folder is trusted (isTrustedFolder())
The refactor replaced shouldConfirmExecute() with getDefaultPermission() but
left out the trust check entirely, adding a comment claiming 'trust logic is
now handled by PM rules' — however no PM rules were ever generated from the
trust setting, making trust: true completely non-functional.
This fix restores the original behavior: MCP tools from a trusted server
(trust: true) auto-approve only when the workspace is also trusted, preserving
the security gate that prevents trust settings from bypassing confirmation in
untrusted folders.
- Add buildHumanReadableRuleLabel() to convert raw permission rules into
natural-language descriptions for the 'Always Allow' UI options
- Add PermissionManager.findMatchingDenyRule() to surface which deny rule
caused a tool to be blocked, improving error messages in coreToolScheduler
- Update ToolConfirmationMessage to use friendly labels with i18n support
- Add comprehensive tests for new permission features and multi-directory
search in glob, grep, and ripGrep tools
- Fix integration test for tool-control allowedTools configuration
- Add PairingStore for managing pending requests and approved users
- Update SenderGate to support pairing policy with code generation
- Add CLI commands: `qwen channel pairing list/approve`
- Document pairing flow with rules and usage examples
This allows unknown senders to request access via a pairing code
that the bot operator approves through the CLI.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add overview page explaining channels architecture and configuration
- Add Telegram channel setup guide with bot creation steps
- Add navigation entries for channels section
This documents the new Channels feature that allows users to interact
with Qwen Code agents from messaging platforms like Telegram.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>