qwen-code/packages/cli
2e69d641d5
Some checks are pending
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
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-8 (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 / 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(core): unescape shell-escaped file paths in Edit, WriteFile, and ReadFile tools (#3820)
* fix(core): unescape shell-escaped file_path in Edit, WriteFile, and ReadFile tools

Shell-escaped paths (e.g. my\ file.txt) from at-completion can reach
the LLM without going through atCommandProcessor unescaping.  When
the LLM passes such an escaped path to a file tool, the backslash is
treated as a literal character in the filename, causing the tool to
fail with file-not-found.

Add defensive unescapePath() normalization at the start of each
tool validateToolParamValues(), so that escaped paths are
converted back to real filesystem paths before any I/O.

Also normalize the path in coreToolScheduler conditional-rules
injection path for consistency.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): harden unescapePath — Windows safety, speculation paths, hooks, and consistency

- Make unescapePath a no-op on win32 to avoid corrupting paths like
  C:\(v2)\file.txt where backslashes are path separators.
- Apply unescapePath in speculationToolGate before overlay FS lookups
  so speculation mode finds files given escaped paths.
- Normalize file_path/path in hook toolInput so custom hooks receive
  actual filesystem paths.
- Add unescapePath to Grep, Glob, Ls, and RipGrep validateToolParamValues
  for parity with the file tools.
- Apply unescapePath in getModifyContext callbacks (Edit, WriteFile) so
  the modify-with-editor flow works when request.args still holds escaped
  paths.
- Add .trim() to Edit and WriteFile path normalization for consistency
  with ReadFile.
- Use .trim() in conditional-rules matchAndConsume for parity.
- Gate literal-backslash test to non-win32; add Windows no-op test for
  unescapePath.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): persist unescaped paths in validators, cover LSP filePath, centralize modifyWithEditor normalization

- Mutate params.path in Glob/Grep/Ls/RipGrep validators so invocations
  receive the normalized path, not the original escaped form.
- Add unescapePath to LspTool.validateToolParamValues for filePath.
- Extend scheduler path normalization to filePath + notebook_path
  keys, mirroring speculationToolGate's key set.
- Move unescapePath from getModifyContext callbacks into
  coreToolScheduler's modifyWithEditor path to avoid double-unescape
  and keep a single normalization site.
- Add .trim() to speculationToolGate paths for consistency.
- Show normalized path in ls.ts validation error message.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): address review feedback for unescapePath PR

- Extract shared PATH_ARG_KEYS constant to eliminate duplicate key lists
  across coreToolScheduler and speculationToolGate
- Add notebook_path to modifyWithEditor unescape block (was missing)
- Hoist unescapePath regex as module-level constant (UNESCAPE_REGEX)
- Add debug log when unescapePath actually modifies a path
- Replace early-return Windows guards with vitest skipIf in tests
- Add tests for escaped paths in Glob, Grep, Ls, RipGrep, LSP validators
- Add test for conditional rules matchAndConsume with unescaped paths

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): fix import order in grep.ts, consolidate ls.ts imports, win32-guard write-file tests

- grep.ts: move debugLogger declaration after all import statements
- ls.ts: consolidate two imports from ../utils/paths.js into one
- write-file.test.ts: add skipIf(process.platform === 'win32') to
  shell-escape tests (unescapePath is a no-op on win32)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): address review — double-unescape, circular import, lsp asymmetry, win32 test guards

- coreToolScheduler.ts: remove redundant unescapePath in conditional-rules
  injection (toolInput was already normalized; unescapePath is not
  idempotent for \\X sequences)
- paths.ts: remove debugLogger to break circular import chain
  (paths → debugLogger → storage → paths). The single debug log line is
  low signal — dropped entirely.
- lsp.ts: remove dead .trim() checks in FILE_REQUIRED_OPERATIONS and
  RANGE_REQUIRED_OPERATIONS (filePath is already trimmed by validator)
- Add it.skipIf(process.platform === 'win32') to 11 escaped-path tests
  across edit.test.ts, read-file.test.ts, glob.test.ts, grep.test.ts,
  ripGrep.test.ts, ls.test.ts, lsp.test.ts

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(test): add win32 skipIf guards to atCommandProcessor, rulesDiscovery, fileSearch tests

Four more escaped-path tests that fail on Windows because
unescapePath is a no-op on win32:
- atCommandProcessor.test.ts: two @-command unescape tests
- rulesDiscovery.test.ts: shell-escaped match test
- fileSearch.test.ts: special-char escaping test

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(test): consolidate duplicate imports in rulesDiscovery.test.ts

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: cici <cici@cicideMacBook-Pro.local>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-05 01:33:36 +08:00
..
src fix(core): unescape shell-escaped file paths in Edit, WriteFile, and ReadFile tools (#3820) 2026-05-05 01:33:36 +08:00
index.ts fix(cli): stop double-wrapping and double-printing API errors in non-interactive mode (#3749) 2026-05-03 08:39:31 +08:00
package.json chore(release): v0.15.6 (#3766) 2026-04-30 15:59:35 +08:00
test-setup.ts fix: prevent bogus shell permission rules in tests 2026-03-20 17:55:33 +08:00
tsconfig.json Add background agent resume and continuation (#3739) 2026-05-01 12:14:33 +08:00
vitest.config.ts refactor(core): Unify package exports and improve dev experience 2026-02-01 11:59:05 +08:00