Skip to content

feat(cli): add configurable plansDirectory for Plan Mode#4062

Open
shenyankm wants to merge 2 commits into
QwenLM:mainfrom
shenyankm:sheny/plan-mode-plans-directory
Open

feat(cli): add configurable plansDirectory for Plan Mode#4062
shenyankm wants to merge 2 commits into
QwenLM:mainfrom
shenyankm:sheny/plan-mode-plans-directory

Conversation

@shenyankm
Copy link
Copy Markdown
Contributor

Summary

  • What changed: Added a plansDirectory setting for Plan Mode so approved plan files can be stored in a project-specific directory instead of always using the global default.
  • Why it changed: This resolves Add configurable plansDirectory setting for Plan Mode (like Gemini CLI / Claude Code) #3548 by allowing users to keep plans inside the project and grant narrower write access for Plan Mode workflows.
  • Reviewer focus: Please review path resolution, rejection of directories outside the project root, and the default fallback behavior when plansDirectory is unset.

Validation

  • Commands run:

    cd packages/core && npx vitest run src/config/storage.test.ts src/config/config.test.ts
    cd packages/cli && npx vitest run src/config/config.test.ts src/config/settingsSchema.test.ts
    npm run build
    npm run typecheck
  • Prompts / inputs used: N/A. This change was validated through focused configuration and storage tests rather than manual TUI interaction.

  • Expected result:

    • Relative plansDirectory values resolve from the project root.
    • Paths outside the project root are rejected.
    • The default plan directory remains ~/.qwen/plans when unset.
    • CLI config, generated schema, docs, and plan persistence remain valid.
  • Observed result:

    • Core config/storage tests passed: 197 tests.
    • CLI config/schema tests passed: 220 tests, 2 skipped.
    • npm run build completed successfully.
    • npm run typecheck completed successfully.
  • Quickest reviewer verification path:

    1. Add "plansDirectory": "./.qwen/plans" to project .qwen/settings.json.
    2. Start Qwen Code from that project.
    3. Enter Plan Mode and approve a plan.
    4. Confirm the plan file is written under .qwen/plans.
    5. Change the setting to "../plans" and confirm startup fails with a configuration error.
  • Evidence:

    • Automated tests cover default behavior, relative and absolute custom directories, path traversal rejection, symlink escape prevention, Windows cross-drive handling, mixed separators, CLI config wiring, schema exposure, and atomic plan writes.

Scope / Risk

  • Main risk or tradeoff: Path validation is intentionally strict; configured plan directories must resolve inside the project root.
  • Not covered / not validated: Manual TUI verification was not run.
  • Breaking changes / migration notes: No breaking change. Existing behavior is preserved when plansDirectory is unset.

Testing Matrix

🍏 🪟 🐧
npm run ⚠️ ⚠️
npx ⚠️ ⚠️
Docker ⚠️ ⚠️ ⚠️
Podman ⚠️ N/A ⚠️
Seatbelt ⚠️ N/A N/A

Testing matrix notes:

  • Validated on Windows only.
  • Docker, Podman, and Seatbelt were not exercised because this change is limited to configuration resolution and plan file path handling, not sandbox behavior.

Linked Issues / Bugs

Closes #3548

shenyankm added 2 commits May 11, 2026 21:22
Add a plansDirectory setting that allows users to define a custom
directory for approved Plan Mode files. Relative paths are resolved
against the project root and validated to prevent path traversal.

- Storage: add isPathWithinDirectory() with realpathSync-based symlink
  resolution to prevent traversal bypass attacks (direct, intermediate,
  and cross-drive)
- Config: cache plansDir at construction time, use atomic write
  (write-temp then rename) to prevent corrupted plan files on crash
- CLI: respect bareMode by clearing plansDirectory in minimal mode
- Docs: document plansDirectory with requiresRestart and gitignore hint
- Tests: 26 new tests covering path validation, symlink attacks
  (direct and intermediate), Windows cross-drive paths, mixed
  separators, and configuration integration

Closes QwenLM#3548
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add configurable plansDirectory setting for Plan Mode (like Gemini CLI / Claude Code)

1 participant