Commit graph

4022 commits

Author SHA1 Message Date
tanzhenxin
b2f04418fa
Merge pull request #2628 from QwenLM/feat/channels-telegram
feat(channels): add extensible Channels platform with plugin system and Telegram/WeChat/DingTalk channels
2026-04-01 16:19:08 +08:00
tanzhenxin
76d64c9464
Merge pull request #2731 from QwenLM/feat/in-session-cron-loops
feat(cron): add in-session loop scheduling with cron tools
2026-04-01 16:18:46 +08:00
tanzhenxin
2eb2f4e319
Merge pull request #2719 from QwenLM/feat/npm-extension-installation
feat(extension): Add npm registry support for extension installation
2026-04-01 16:18:17 +08:00
tanzhenxin
63f1963377
Merge pull request #2698 from QwenLM/refactor/subagent-model-selection
feat: add cross-provider model selection for subagents
2026-04-01 16:17:54 +08:00
tanzhenxin
cd47e9b653
Merge pull request #2666 from qqqys/feat/vscode-acp-reconnect-logic
feat(vscode): add retry logic and auto-reconnect for ACP connection
2026-04-01 16:17:46 +08:00
tanzhenxin
449a421ca7
Merge pull request #2612 from qqqys/fix/ime_vscode
fix(cli): enhance KeypressProvider with kitty sequence timeout manage…
2026-04-01 16:10:02 +08:00
DennisYu07
06a0f4797d
Merge pull request #2696 from QwenLM/feat/hooks-refactor-ui-event
refactor(ui): improve hook event handling with dedicated history items
2026-04-01 15:56:17 +08:00
tanzhenxin
2f40c30160
Merge pull request #2662 from QwenLM/fix/acp-orphan-subprocess-cleanup
fix: prevent orphan ACP processes on tab close and clean up MCP subprocesses on shutdown
2026-04-01 15:44:12 +08:00
tanzhenxin
a55a986e1e
Merge pull request #2687 from QwenLM/enhance/review-verification-and-pr-comments
Enhance /review: add verification, false positive control, and PR comments
2026-04-01 15:43:28 +08:00
tanzhenxin
311f971ba7
Merge pull request #2763 from QwenLM/fix/2754-allow-webfetch-in-plan-mode
fix: allow web fetch approvals in plan mode
2026-04-01 15:41:03 +08:00
tanzhenxin
f70cc05bbc
Merge pull request #2777 from QwenLM/fix/pty-fd-leak-upgrade-node-pty
fix: upgrade @lydell/node-pty to 1.2.0-beta.10 to fix PTY FD leak on macOS
2026-04-01 15:38:13 +08:00
qqqys
ca6cf82add Merge branch 'main' of https://github.com/qqqys/qwen-code into feat/vscode-acp-reconnect-logic 2026-04-01 15:38:09 +08:00
tanzhenxin
2489044e61
Merge pull request #2765 from QwenLM/fix/subagent-token-leak-footer
fix: prevent subagent telemetry from overwriting main agent footer context
2026-04-01 15:37:55 +08:00
tanzhenxin
a29e059d2e
Merge pull request #2781 from QwenLM/feat/hooks-remove-experimental
feat(hooks): remove experimental flag and add disabled state UI
2026-04-01 15:37:34 +08:00
tanzhenxin
32f3339908
Merge pull request #2764 from LaZzyMan/fix/tree-sitter-symlink-wasm
fix(core): robustly resolve tree-sitter WASM path for symlinked CLI installations
2026-04-01 15:37:06 +08:00
tanzhenxin
92132ec8fa
Merge pull request #2659 from QwenLM/fix/compress-split-point-tool-heavy-conversations
fix: make /compress handle tool-heavy conversations correctly
2026-04-01 15:36:56 +08:00
qqqys
d169aeb3ca Merge branch 'main' of https://github.com/qqqys/qwen-code into fix/ime_vscode 2026-04-01 15:34:36 +08:00
DennisYu07
3585b9e32d fix issue 2026-04-01 15:27:28 +08:00
LaZzyMan
38aa1a6aa2 fix lint 2026-04-01 14:33:29 +08:00
DennisYu07
4b05c74b02
Merge pull request #2745 from QwenLM/fix/proxy-url-compability
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
fix: normalize proxy URLs to support addresses without protocol prefix
2026-04-01 14:30:29 +08:00
DennisYu07
3d5bb357c1 add markdown display 2026-04-01 14:00:52 +08:00
DennisYu07
b4d2ba2a56 remove test case 2026-04-01 13:39:51 +08:00
DennisYu07
a32ab3a58f fix test 2026-04-01 12:48:15 +08:00
tanzhenxin
46bd05eaf1 fix(channels/telegram): migrate from telegraf to grammy
Replace Telegraf with Grammy as the Telegram Bot framework.

- Replace @telegraf/types with @grammyjs/types in package-lock.json
- Swap telegraf dependency for grammy ^1.41.1 in package.json
- Update TelegramAdapter.ts: Bot instead of Telegraf, .api.* instead
  of .telegram.* calls, .start() instead of .launch(), adjusted event
  subscription syntax (message:text, message:photo, message:document)

Grammy is a more modern and actively maintained Telegram bot framework
for Node.js, improving reliability and reduce legacy dependencies.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-01 04:28:14 +00:00
tanzhenxin
f61517c40c chore(channels): add plugin-example to build pipeline and prepublish script
- Add plugin-example to build order in scripts/build.js
- Add prepublishOnly script to auto-build before npm publish

This ensures the plugin-example package is built during the main build process and automatically compiled before publishing to npm.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-01 12:22:33 +08:00
DennisYu07
9c26c7fe85 add more notes 2026-04-01 12:04:37 +08:00
DennisYu07
5221002831 remove hooks experimental and refactor hook Config 2026-04-01 11:50:23 +08:00
tanzhenxin
89b79544d1 fix: upgrade @lydell/node-pty to 1.2.0-beta.10 to fix PTY FD leak
The previous version (1.1.0) has a native-level bug on macOS where each
PTY spawn leaks one /dev/ptmx file descriptor that is never closed. Over
a long session with hundreds of shell commands, this exhausts the
system-wide PTY pool (kern.tty.ptmx_max = 511), breaking other programs
like tmux and new terminal windows.

Root cause: microsoft/node-pty#882

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-01 07:55:56 +08:00
pomelo
20e51e3d30
Merge pull request #2769 from QwenLM/fix/qwen-path-replacement-in-md-files
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
fix: add .qwen path replacement in markdown files during extension install
2026-03-31 22:22:26 +08:00
DennisYu07
1a7510d85e fix loss of stopHookCount 2026-03-31 20:22:51 +08:00
DennisYu07
3c484782ec fix: replace .claude paths with .qwen in markdown files during extension install
Previously, only shell scripts (.sh) had .claude -> .qwen path replacement.
Markdown files (.md) like cancel-ralph.md and help.md were missing this
conversion, causing incorrect paths like .claude/ralph-loop.local.md.

Now performVariableReplacement also replaces .claude directory references
in markdown files using the same regex pattern as shell scripts.
2026-03-31 19:47:03 +08:00
tanzhenxin
3d8f56a207 fix: prevent subagent telemetry from overwriting main agent footer context
Root cause: PR #1835 accidentally overwrote PR #1912's correct telemetry
isolation during a merge conflict resolution. This restores the original
guard logic so subagent GeminiChat instances (which don't receive a
telemetryService param) no longer write to the global uiTelemetryService.

- Remove unused uiTelemetryService import from geminiChat.ts
- Guard telemetry calls with this.telemetryService checks
- Add test verifying subagent isolation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-31 09:15:51 +00:00
LaZzyMan
ee08ae9e7e fix: allow web fetch approvals in plan mode 2026-03-31 16:30:44 +08:00
LaZzyMan
ce2f1902b9 fix(core): add regex-based fallback when tree-sitter WASM fails to load
When the WASM files cannot be found (e.g. symlinked CLI whose vendor path
probe still fails, or any other I/O error), isShellCommandReadOnlyAST and
initParser previously left the agent in a permanently broken state:
  - initParser() returned a rejected promise stored in initPromise, so every
    subsequent call returned the same rejection immediately
  - isShellCommandReadOnlyAST() propagated the error to its caller, which
    caused the shell tool to throw and left the agent 'thinking forever'

Changes:
- Import isShellCommandReadOnly from shellReadOnlyChecker.js
- Track parserInitFailed: boolean flag on the parser singleton
- initParser(): on any init error, set parserInitFailed=true and reset
  initPromise=null (preventing permanent hang on the rejected promise)
- isShellCommandReadOnlyAST(): check parserInitFailed before attempting
  AST parse; wrap the AST path in try/catch so any unexpected runtime
  error also falls through to the regex checker
- _resetParser(): also resets parserInitFailed so tests can re-initialise
- Export _setParserFailedForTesting() to allow unit tests to exercise the
  fallback path without breaking actual WASM loading

Tests added:
- Fallback suite: verifies that when the parser is marked as failed, all
  isShellCommandReadOnlyAST calls delegate to isShellCommandReadOnly and
  that _resetParser() restores normal AST operation
- Consistency suite: 40+ commands from shellReadOnlyChecker.test.ts run
  through BOTH implementations; every case must agree. Known intentional
  divergences (pure assignment, process substitution, control flow,
  function definitions) are documented explicitly - all happen to agree
  on the same boolean result, confirming the two implementations are
  behaviourally consistent across the tested corpus

Fixes #2758
2026-03-31 15:23:51 +08:00
LaZzyMan
9f4bd9be5e fix(core): probe vendor directory existence to resolve WASM path robustly
The previous fix used fs.realpathSync(fileURLToPath(import.meta.url)) to
resolve symlinks before computing the WASM path.  This works in the common
case (/usr/bin/qwen → /usr/lib/node_modules/.../cli.js), but silently falls
back to the unresolved symlink path when:

  - realpathSync throws (ENOENT, EACCES, ELOOP, or other OS-level errors)
  - Node.js has already resolved import.meta.url to the real path on some
    platforms (making realpathSync a no-op and the first candidate correct),
    but the vendor files are still not found at that location

The new approach for the bundle case (inSrcUtils = false) collects up to four
candidate directories:

  1. path.dirname(fileURLToPath(import.meta.url))  — already resolved on
     Node.js 18+ on most platforms
  2. path.dirname(realpathSync(import.meta.url))   — symlink-resolved fallback
  3. path.dirname(process.argv[1])                 — entry point as invoked
  4. path.dirname(realpathSync(process.argv[1]))   — resolved entry point

It then calls fs.existsSync on each candidate path for the requested .wasm
file and returns the first one that actually exists, rather than trusting
that a single path computation is correct.  If none exist we fall back to
the first candidate so the caller still gets a deterministic ENOENT (instead
of silently using a wrong path).

Fixes #2758
2026-03-31 15:00:37 +08:00
tanzhenxin
7bbd5e6471 fix(channels): address PR review — security, bugs, and reliability
- fix: sanitize remote filenames with basename() and isolate uploads
  in UUID subdirs to prevent path traversal and collision (#2-4, #27)
- fix: use crypto.randomInt() for pairing codes instead of Math.random() (#5)
- fix: pass config.sessionScope instead of hardcoded 'user' (#6);
  add per-channel scope overrides via setChannelScope() for startAll (#7)
- fix: removeSession now returns removed session IDs and persists
  when chatId is provided (#8)
- fix: /clear only removes the cleared session from instructedSessions,
  not all sessions (#9)
- fix: DingTalk @mention stripping now removes only the first mention
  instead of all mentions (#10)
- fix: remove dead TELEGRAF_COMMANDS Set and its guard (#13)
- fix: WeChat cursor saved after message processing, not before (#14)
- fix: crash recovery uses time-window counting instead of resettable
  counter to prevent infinite restart loops (#17)
- fix: call channel.disconnect() before exit on crash exhaustion (#18)
2026-03-31 00:57:59 +00:00
tanzhenxin
1e44fc8c88 fix(cron): correct jitter handling for delayed and advanced fire times
- Scan a window of minutes around current time to find matching cron minutes
- Track matched cron minute in lastFiredAt instead of wall-clock time
- Add tests for positive jitter (recurring) and negative jitter (one-shot)

This ensures jittered jobs fire correctly when their delayed or advanced
fire time falls outside the original matching minute.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 20:25:09 +08:00
tanzhenxin
05f38543cf fix(cron): prevent concurrent cron execution and queue properly
- Add queue-based cron processing in nonInteractiveCli for sequential execution
- Block cron processing while user prompt is active in Session
- Drain cron queue after prompt completion to process queued jobs
- Reduce recurring task auto-expiry from 7 days to 3 days

This fixes race conditions where cron jobs could fire during active prompts
and ensures cron prompts are processed sequentially.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 19:49:17 +08:00
tanzhenxin
ec677383b9 fix(npm): prevent auth token leakage on cross-host redirects
- Strip auth token when following redirects to a different host
- Strip auth token when downloading tarballs from a different host
- Fix package name encoding to replace all slashes, not just the first

This prevents credentials from being sent to unintended hosts when
private registries redirect to CDNs or other external domains.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 19:48:54 +08:00
tanzhenxin
dbc86e7672 test(session): add isCronEnabled mock to test config
Adds missing isCronEnabled mock function to the test configuration
to support the cron feature implementation.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 11:17:23 +00:00
tanzhenxin
7962d4f790 Merge remote-tracking branch 'origin/main' into feat/channels-telegram 2026-03-30 19:17:22 +08:00
tanzhenxin
2c1432a23a Merge remote-tracking branch 'origin/main' into feat/npm-extension-installation 2026-03-30 19:16:08 +08:00
tanzhenxin
9a8829c5a5 merge: resolve conflict in client.ts hook condition
Keep both changes: SendMessageType.Cron skip from our branch
and hasHooksForEvent check from main.
2026-03-30 18:06:59 +08:00
tanzhenxin
9dd22eb152 feat(cron): integrate cron scheduling into ACP session lifecycle
- Add cron queue and scheduler state management to Session class
- Handle cron cancellation on user prompt and cancelPendingPrompt
- Start cron scheduler after prompt execution completes
- Drain cron queue sequentially to prevent concurrent chat access
- Execute cron prompts with proper message echoing and tool handling
- Add integration test for cron firing and sessionUpdate streaming

This enables cron jobs created during an ACP session to fire in the
background and stream results back to the client via sessionUpdate
notifications, even after the originating prompt has returned.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 18:06:09 +08:00
tanzhenxin
fd58818f58 fix(subagents): treat unknown prefixes as bare model IDs
Model IDs can legitimately contain colons (e.g., `gpt-4o:online`).
Previously, any string with a colon was parsed as `authType:modelId`,
which caused valid model IDs with colons to be rejected.

Now, if the prefix before a colon isn't a known AuthType, the entire
string is treated as a bare model ID.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 18:03:33 +08:00
LaZzyMan
501f80a514 fix: handle orphaned funcCall and improve compression logic for tool-heavy conversations
- Strip trailing orphaned funcCall (force=true) before split point calculation,
  so normal compression logic runs cleanly on the remaining history instead of
  requiring ad-hoc special-casing
- Remove redundant lastToolCompletionSplitPoint machinery: after fixing the
  i+2 index bug, lastSplitPoint already subsumes it, making Math.max redundant
- Add MIN_COMPRESSION_FRACTION constant (0.05) to guard against futile API
  calls when historyToCompress is too small relative to total history
- Add tests for orphaned funcCall handling (force=true compresses, force=false NOOP)
- Add test for MIN_COMPRESSION_FRACTION guard

Fixes #2647
2026-03-30 18:00:27 +08:00
tanzhenxin
4293641d14 test(models): add tests for content-generator-config helpers
Add comprehensive tests for buildAgentContentGeneratorConfig and
resolveCredentialField, covering same-provider overrides, cross-provider
credential clearing, registry-resolved models, and edge cases.

This ensures correct model selection behavior for subagent configurations.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 09:35:41 +00:00
tanzhenxin
7b29d1f4a3 fix(subagents): ensure model selection works for bare model IDs
- Handle bare model IDs by inheriting parent's authType
- Create dedicated ContentGenerator for any explicit model selection
- Add tests for model override scenarios

Previously, only cross-provider prefixed models (e.g., "openai:gpt-4o")
triggered ContentGenerator creation. Bare IDs like "qwen-coder" were
ignored, causing subagents to always use the parent's model.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 09:33:54 +00:00
tanzhenxin
aa454a5a72 feat(cron): add distinct Cron message type and exit summary
- Introduce SendMessageType.Cron to differentiate cron-triggered prompts
  from user queries
- Skip UserPromptSubmit hook for cron messages
- Add getExitSummary() to display active loops when session ends
- Add tests for exit summary functionality

This improves cron loop handling by treating scheduled prompts
differently from user-initiated queries and provides better UX
when sessions end with active loops running.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 17:00:19 +08:00
tanzhenxin
7ffadfbaf7 feat(subagents): enable cross-provider model selectors
- Extract buildAgentContentGeneratorConfig to shared module for reuse
- Create per-agent ContentGenerator when subagent uses different provider
- Remove validation restriction on cross-provider model selectors
- Update tests to accept cross-provider selectors

This allows subagents to use models from different providers (e.g.,
"openai:gpt-4" when parent uses Qwen) by creating dedicated
ContentGenerators with proper auth credentials.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-30 08:44:13 +00:00