Skip to content

feat(storage): support configurable runtime output directory#2127

Merged
yiliang114 merged 12 commits into
QwenLM:mainfrom
yiliang114:feat/configurable-runtime-output-dir
Mar 20, 2026
Merged

feat(storage): support configurable runtime output directory#2127
yiliang114 merged 12 commits into
QwenLM:mainfrom
yiliang114:feat/configurable-runtime-output-dir

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

TLDR

Support configurable runtime output directory, allowing users to redirect runtime output (temp files, debug logs, session data, todos, insights, etc.) to a custom directory via the advanced.runtimeOutputDir setting or the QWEN_RUNTIME_DIR environment variable, while config files (settings.json, oauth, installation_id, etc.) remain at ~/.qwen.

This is an initial implementation for issue #2014, providing flexible runtime output path management for enterprise Agent deployment scenarios.

Dive Deeper

Core Design

  1. Storage class extensions (packages/core/src/config/storage.ts):

    • Added setRuntimeBaseDir() / getRuntimeBaseDir() static methods
    • Supports tilde (~) expansion and relative path resolution (with optional cwd base directory)
    • Priority: QWEN_RUNTIME_DIR env var > setRuntimeBaseDir() value > getGlobalQwenDir() default
    • Uses AsyncLocalStorage to implement runWithRuntimeBaseDir() for isolating runtime paths across concurrent ACP sessions
  2. Path classification:

    • Runtime paths (follow getRuntimeBaseDir()): tmp/, debug/, ide/, projects/, history/, todos/, insights/
    • Config paths (pinned to ~/.qwen): settings.json, oauth_creds.json, installation_id, google_accounts.json, mcp-oauth-tokens.json, commands/, memory.md, bin/, skills/
  3. Settings integration (packages/cli/src/config/settingsSchema.ts + config.ts):

    • Added runtimeOutputDir string setting under the advanced category
    • loadCliConfig() calls Storage.setRuntimeBaseDir() during initialization
  4. ACP session isolation (packages/cli/src/acp-integration/session/Session.ts):

    • Session snapshots the current runtimeBaseDir at construction time
    • prompt() wraps execution in Storage.runWithRuntimeBaseDir() to ensure concurrent sessions have isolated paths
  5. Adapted modules:

    • StaticInsightGenerator: insight output directory
    • insightCommand: projects directory lookup
    • todoWrite: todo file read/write

Test Coverage

  • storage.test.ts: Path resolution, env var priority, tilde expansion, relative paths, null/undefined/empty string reset, runtime path methods, config path stability, AsyncLocalStorage concurrent isolation
  • config.test.ts: loadCliConfig runtimeOutputDir settings integration
  • Session.test.ts: ACP session runWithRuntimeBaseDir invocation verification
  • StaticInsightGenerator.test.ts: Insight output uses runtime directory
  • insightCommand.test.ts: Insight command uses runtime directory
  • todoWrite.test.ts: Todo read/write uses runtime directory

Reviewer Test Plan

  1. Pull the branch and run npm run test to confirm all tests pass
  2. Add to ~/.qwen/settings.json:
    { "advanced": { "runtimeOutputDir": "/tmp/qwen-runtime-test" } }
  3. Start qwen-code and verify debug logs, todo files, etc. are written under /tmp/qwen-runtime-test/
  4. Set env var QWEN_RUNTIME_DIR=/tmp/qwen-env-test and verify the env var takes priority over the setting
  5. Verify ~/.qwen/settings.json and other config files are unaffected
  6. Remove the custom config and verify fallback to the default ~/.qwen directory

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Closes #2014

…2014)

Add `advanced.runtimeOutputDir` setting and `QWEN_RUNTIME_DIR` env var
to redirect runtime output (temp files, debug logs, session data, todos,
insights) to a custom directory while keeping config files at ~/.qwen.

- Introduce `Storage.setRuntimeBaseDir()` / `getRuntimeBaseDir()` with
  tilde expansion and relative path resolution
- Add `AsyncLocalStorage`-based `runWithRuntimeBaseDir()` for concurrent
  session isolation in ACP integration
- Update all runtime path methods to use `getRuntimeBaseDir()` instead
  of `getGlobalQwenDir()` (temp, debug, ide, projects, history dirs)
- Config paths (settings, oauth, installation_id, etc.) remain pinned
  to `~/.qwen` regardless of runtime dir configuration
- Add comprehensive tests covering path resolution, env var priority,
  async context isolation, and config path stability
@github-actions

github-actions Bot commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

📋 Review Summary

This PR introduces a configurable runtime output directory feature, allowing users to redirect temporary files, debug logs, and other runtime data to a custom location via settings or environment variables. The implementation is well-architected with proper path resolution, tilde expansion, and async context isolation for concurrent sessions.

🔍 General Feedback

  • The implementation follows a clean architecture with the Storage class serving as the central point for managing runtime paths
  • Comprehensive test coverage is provided for all the new functionality including path resolution, environment variable priority, and async context isolation
  • Good separation between runtime paths (which can be redirected) and config paths (which remain at ~/.qwen)
  • The AsyncLocalStorage implementation for concurrent session isolation is well-designed

🎯 Specific Feedback

🟡 High

  • File: packages/core/src/config/storage.ts:112 - The resolveRuntimeBaseDir method has a potential security concern where relative paths could lead to directory traversal if untrusted input is accepted. Consider adding validation to ensure resolved paths remain within expected boundaries.
  • File: packages/core/src/config/storage.ts:148 - The priority order (QWEN_RUNTIME_DIR env var > setRuntimeBaseDir() value > getGlobalQwenDir()) is well documented, but consider adding a warning log when the environment variable overrides the settings file value to alert users of potential configuration conflicts.

🟢 Medium

  • File: packages/cli/src/acp-integration/session/Session.ts:140 - The prompt method is wrapped in Storage.runWithRuntimeBaseDir, which is great for isolation, but consider adding error handling around this call to catch any issues with the context switching.
  • File: packages/core/src/config/storage.ts:106 - The documentation for setRuntimeBaseDir mentions passing the project root as cwd for relative path resolution, but there's no validation to ensure the resulting path is secure. Consider adding path validation to prevent access to unintended directories.

🔵 Low

  • File: packages/cli/src/config/settingsSchema.ts:108 - Consider adding a more descriptive title and description for the runtimeOutputDir setting to help users understand its purpose and usage.
  • File: packages/core/src/config/storage.ts:131 - The comment mentions that config paths remain at ~/.qwen regardless of runtime dir configuration, which is good. Consider adding a brief explanation in the README or documentation about which paths are affected by this setting versus which remain constant.

✅ Highlights

  • Excellent test coverage with dedicated test suites for runtime base directory functionality, path resolution, and async context isolation
  • Smart implementation of AsyncLocalStorage for concurrent session isolation in ACP integration
  • Proper separation of concerns with runtime paths vs config paths
  • Good use of tilde expansion and relative path resolution with configurable base directory
  • Well-documented code with clear JSDoc comments explaining the priority order and behavior

yiliang114 and others added 6 commits March 11, 2026 14:50
…time-output-dir

# Conflicts:
#	packages/cli/src/acp-integration/service/filesystem.ts
#	packages/cli/src/acp-integration/session/Session.ts
#	packages/cli/src/services/insight/generators/StaticInsightGenerator.ts
扩展 setRuntimeBaseDir 以支持 Windows 风格的波浪号路径 (~\),
使用统一的路径分割逻辑处理 Unix 和 Windows 风格的路径分隔符

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
添加 ensuredDebugDirPath 追踪变量,当 runtime base dir 发生变更时,
确保在新的目录下创建 debug 子目录

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
新增 runWithAcpRuntimeOutputDir 辅助函数,在 ACP Agent 的
loadSession 和 listSessions 操作中应用配置的 runtimeOutputDir

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
为 self = this 的用法添加解释性注释,说明在嵌套回调中需要使用 this

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

@tanzhenxin tanzhenxin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Update storage.test.ts to call getUserSkillsDirs() instead of the
non-existent getUserSkillsDir() method. The method was renamed to
return an array of skill directories.
…in test

Replace hardcoded forward-slash path `.qwen/todos/` with `path.join('.qwen', 'todos')` to fix Windows CI failure where paths use backslashes.

Made-with: Cursor
@yiliang114 yiliang114 merged commit fbf5ed5 into QwenLM:main Mar 20, 2026
13 checks passed
xaelistic pushed a commit to xaelistic/qwen-code that referenced this pull request Jun 7, 2026
…2127)

* feat(storage): support configurable runtime output directory (QwenLM#2014)

Add `advanced.runtimeOutputDir` setting and `QWEN_RUNTIME_DIR` env var
to redirect runtime output (temp files, debug logs, session data, todos,
insights) to a custom directory while keeping config files at ~/.qwen.

- Introduce `Storage.setRuntimeBaseDir()` / `getRuntimeBaseDir()` with
  tilde expansion and relative path resolution
- Add `AsyncLocalStorage`-based `runWithRuntimeBaseDir()` for concurrent
  session isolation in ACP integration
- Update all runtime path methods to use `getRuntimeBaseDir()` instead
  of `getGlobalQwenDir()` (temp, debug, ide, projects, history dirs)
- Config paths (settings, oauth, installation_id, etc.) remain pinned
  to `~/.qwen` regardless of runtime dir configuration
- Add comprehensive tests covering path resolution, env var priority,
  async context isolation, and config path stability

* fix(core/storage): 支持 Windows 风格波浪号路径

扩展 setRuntimeBaseDir 以支持 Windows 风格的波浪号路径 (~\),
使用统一的路径分割逻辑处理 Unix 和 Windows 风格的路径分隔符

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

* fix(core/debugLogger): runtime base dir 变更时创建新 debug 目录

添加 ensuredDebugDirPath 追踪变量,当 runtime base dir 发生变更时,
确保在新的目录下创建 debug 子目录

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

* feat(cli/acp): 支持 ACP runtime output dir 配置

新增 runWithAcpRuntimeOutputDir 辅助函数,在 ACP Agent 的
loadSession 和 listSessions 操作中应用配置的 runtimeOutputDir

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

* docs(vscode-ide-companion/acpConnection): 补充 this 别名的使用说明

为 self = this 的用法添加解释性注释,说明在嵌套回调中需要使用 this

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

* feat(cli): add runtime output directory configuration support

* fix(core): update test to use getUserSkillsDirs method

Update storage.test.ts to call getUserSkillsDirs() instead of the
non-existent getUserSkillsDir() method. The method was renamed to
return an array of skill directories.

* fix(core/todoWrite): use path.join for cross-platform path assertion in test

Replace hardcoded forward-slash path `.qwen/todos/` with `path.join('.qwen', 'todos')` to fix Windows CI failure where paths use backslashes.

Made-with: Cursor

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Support standalone structured error log output for external monitoring integration

2 participants