fix(tui_gateway): honor target profile's terminal.cwd on desktop profile switch#40892
Conversation
…ile switch The desktop's app-global remote mode serves every profile from one tui_gateway backend, so the process-global TERMINAL_CWD only reflects the launch profile. After switching profiles, a new session resolved its workspace from that stale env var and inherited the previous profile's directory. Add _profile_configured_cwd() to read a non-launch profile's own terminal.cwd from its config.yaml (skipping placeholder/empty/missing and non-existent paths so callers fall back cleanly), and wire it into _completion_cwd() with precedence: explicit client cwd -> existing session cwd -> bound profile's configured cwd -> TERMINAL_CWD -> os.getcwd(). Fixes NousResearch#40334
Pin the new contract: _profile_configured_cwd reads a profile's own terminal.cwd and rejects placeholders/missing paths, and _completion_cwd prefers a bound profile's cwd over a stale launch-profile TERMINAL_CWD while still letting an explicit client cwd win.
7dc9617 to
fc69e57
Compare
|
感谢该 PR 解决了网关端读取 Profile 自身 的问题。从文档(profile-switch-terminal-cwd-fix.md)中可以看到,Hermes 原本的设计意图是 Profile 与 Workspace 正交(模式 B),即 Profile 决定 AI/工具,Workspace 决定当前工作目录。用户实际上也存在一种 “Profile‑Project 一对一” 的使用习惯(模式 A),即切 Profile 期望自动跳到该 Profile 配置的 。当前补丁在网关端实现了 profile‑first 的优先级,能够完美修复模式 A 下的 bug。但正如文档所列的对比表所示,这会在模式 B 下引入新问题:用户在侧边栏工作区列表点击 “+” 时,所选的 Workspace 会被 Profile 默认目录覆盖。为了同时兼容两种使用模式,文档提出了一种 “温和版 scheme D + explicit_cwd 标记” 的完整方案:1. Desktop 端在显式选择 Workspace 时设置 = true,切 Profile 时复位;2. 创建会话时把该标记随 RPC 发送;3. 网关端在收到 profile 参数时,只有当 explicit_cwd 为 false 时才使用 Profile 自身的 terminal.cwd;否则尊重 params.cwd。这样既保证了模式 A 的自动跳转,又不破坏模式 B 的灵活性。请问是否可以在后续的迭代中考虑加入这一标记机制?如果目前的补丁已经足够满足当前的紧急需求,我们也可以先合并此 PR,并在后续的 Issue 中跟进完整的正交方案。期待维护者的意见,并愿意为实现该标记提供代码或测试上的帮助。 |
|
感谢该 PR 解决了网关端读取 Profile 自身 |
OutThisLife
left a comment
There was a problem hiding this comment.
Approving. I traced the resolution path rather than going off the description:
_completion_cwdis the session cwd seed, not just autocomplete:session.createstores_completion_cwd(params)as the session'scwdand passesprofilein params, so this lands on the exact path #40334 exercises (/reset/ new session under a switched-to profile).- Precedence reads correctly: explicit client cwd > existing session cwd > bound profile config >
TERMINAL_CWD>os.getcwd(). The bound profile's explicit config should beat the launch profile's stale env var, and it does. - No-profile / launch sessions:
_profile_home(None)returnsNone, the resolver returnsNone, and it falls through toTERMINAL_CWDunchanged. No regression for single-profile use. _CWD_PLACEHOLDERSmatchesgateway/run.pyexactly, and empty/missing/non-existent dirs fall back cleanly.- The 4 hermetic tests cover the #40334 regression and the explicit-cwd-wins case. CI is green and the branch is clean against main.
LGTM.
…ile switch (NousResearch#40892) * fix(tui_gateway): honor target profile's terminal.cwd on desktop profile switch The desktop's app-global remote mode serves every profile from one tui_gateway backend, so the process-global TERMINAL_CWD only reflects the launch profile. After switching profiles, a new session resolved its workspace from that stale env var and inherited the previous profile's directory. Add _profile_configured_cwd() to read a non-launch profile's own terminal.cwd from its config.yaml (skipping placeholder/empty/missing and non-existent paths so callers fall back cleanly), and wire it into _completion_cwd() with precedence: explicit client cwd -> existing session cwd -> bound profile's configured cwd -> TERMINAL_CWD -> os.getcwd(). Fixes NousResearch#40334 * test(tui_gateway): cover per-profile cwd resolution (NousResearch#40334) Pin the new contract: _profile_configured_cwd reads a profile's own terminal.cwd and rejects placeholders/missing paths, and _completion_cwd prefers a bound profile's cwd over a stale launch-profile TERMINAL_CWD while still letting an explicit client cwd win.
|
Thanks for the detailed review and approval! LGTM as well.
在 2026-06-10 06:13:51,brooklyn! ***@***.***> 写道:
@OutThisLife approved this pull request.
Approving. I traced the resolution path rather than going off the description:
_completion_cwd is the session cwd seed, not just autocomplete: session.create stores _completion_cwd(params) as the session's cwd and passes profile in params, so this lands on the exact path #40334 exercises (/reset / new session under a switched-to profile).
Precedence reads correctly: explicit client cwd > existing session cwd > bound profile config > TERMINAL_CWD > os.getcwd(). The bound profile's explicit config should beat the launch profile's stale env var, and it does.
No-profile / launch sessions: _profile_home(None) returns None, the resolver returns None, and it falls through to TERMINAL_CWD unchanged. No regression for single-profile use.
_CWD_PLACEHOLDERS matches gateway/run.py exactly, and empty/missing/non-existent dirs fall back cleanly.
The 4 hermetic tests cover the #40334 regression and the explicit-cwd-wins case. CI is green and the branch is clean against main.
LGTM.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you commented.Message ID: ***@***.***>
|
…ile switch (NousResearch#40892) * fix(tui_gateway): honor target profile's terminal.cwd on desktop profile switch The desktop's app-global remote mode serves every profile from one tui_gateway backend, so the process-global TERMINAL_CWD only reflects the launch profile. After switching profiles, a new session resolved its workspace from that stale env var and inherited the previous profile's directory. Add _profile_configured_cwd() to read a non-launch profile's own terminal.cwd from its config.yaml (skipping placeholder/empty/missing and non-existent paths so callers fall back cleanly), and wire it into _completion_cwd() with precedence: explicit client cwd -> existing session cwd -> bound profile's configured cwd -> TERMINAL_CWD -> os.getcwd(). Fixes NousResearch#40334 * test(tui_gateway): cover per-profile cwd resolution (NousResearch#40334) Pin the new contract: _profile_configured_cwd reads a profile's own terminal.cwd and rejects placeholders/missing paths, and _completion_cwd prefers a bound profile's cwd over a stale launch-profile TERMINAL_CWD while still letting an explicit client cwd win.
What does this PR do?
Fixes a profile-isolation bug in the desktop app: after switching profiles, a newly-started session inherited the previous profile's working directory instead of the directory configured in the profile you switched to.
The desktop's app-global remote mode serves every local profile from one
tui_gatewaybackend, so the process-globalTERMINAL_CWDenv var only ever reflects the launch profile. When a new session was bound to another profile,_completion_cwd()resolved its workspace straight from that stale env var and never consulted the target profile's ownconfig.yaml.This PR teaches the session-cwd resolver to read the bound profile's configured
terminal.cwdfirst:_profile_configured_cwd(profile_home)— readsterminal.cwdfrom a non-launch profile'sconfig.yaml, skipping placeholder (./auto/cwd), empty, missing, and non-existent-directory values so callers fall back cleanly (mirrors the placeholder handling ingateway/run.py's config bridge)._completion_cwd()with the correct precedence: explicit clientcwd→ existing sessioncwd→ bound profile's configured cwd →TERMINAL_CWDenv →os.getcwd().When no profile is passed (single-profile / launch-profile sessions)
_profile_home()returnsNoneand behavior is unchanged.Related Issue
Fixes #40334
Type of Change
Changes Made
tui_gateway/server.py:_profile_configured_cwd()+ a shared_CWD_PLACEHOLDERSconstant (+34 lines)._completion_cwd()now prefers the bound profile's configuredterminal.cwdover the launch profile'sTERMINAL_CWD(+6/-2 lines).tests/test_tui_gateway_server.py— added 4 tests (+58 lines):test_profile_configured_cwd_reads_target_profile— readsterminal.cwdfrom a profile's ownconfig.yaml.test_profile_configured_cwd_skips_placeholders_and_missing—None, missing dir,./auto/cwd/empty placeholders, and non-existent paths all fall through.test_completion_cwd_prefers_profile_over_stale_env— the Desktop: profile switch ignores terminal.cwd, uses wrong profile's working directory #40334 regression: a profile-bound session uses its own cwd, not the stale launchTERMINAL_CWD; no-profile still falls back to the env var.test_completion_cwd_explicit_cwd_wins_over_profile— an explicit client cwd still wins.How to Test
source .venv/bin/activate(orvenv).*_cwdtests pass alongside the existing suite.terminal.cwd./reset), ask the agent topwd.terminal.cwd.Checklist
Code
fix(tui_gateway): .../test(tui_gateway): ...)scripts/run_tests.sh tests/test_tui_gateway_server.pyand the new tests passDocumentation & Housekeeping
docs/, docstrings) — N/A (internal resolver, no user-facing surface change)cli-config.yaml.exampleif I added/changed config keys — N/A (no new config keys)CONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/Atmp_path+monkeypatch)Screenshots / Logs