【Bug已解决】`/resume` picker does not show CWD filter when Codex is launched with `--remote ... --cd`...
·
【Bug已解决】/resume picker does not show CWD filter when Codex is launched with --remote ... --cd 解决方案
原始报错线索:
/resumepicker does not show CWD filter when Codex is launched with--remote ... --cd(当用--remote ... --cd参数远程启动时,「恢复会话」的选择器没有显示按当前工作目录过滤的选项)。
一、现象长什么样
用户这样启动程序:
codex --remote myhost --cd /projects/foo
然后想恢复一个会话,打开 /resume 选择器,期望能「按当前工作目录 /projects/foo 过滤」:
- 选择器里没有 CWD 过滤选项;
- 选择器把所有目录的会话混在一起,没法按
--cd指定的目录筛; - 但如果不加
--remote,本地启动时 CWD 过滤又是有的; - 说明:
--cd的值在某个环节丢失了,没传到选择器。 根因是启动参数解析后,部分上下文(--cd)没有被保留并传递给后续的会话恢复功能。
二、背景:启动上下文应贯穿全程
程序启动时的关键信息(远程主机、工作目录、用户、环境)构成「启动上下文」,它应当在整个进程生命周期内可被各子功能读取:
- 主对话要用
--cd决定初始目录; /resume选择器要用--cd提供过滤;- 文件操作要用
--cd作为默认根。 若启动参数只被「主对话」消费、--cd用完即弃,后续子功能就缺上下文。
三、为什么 CWD 过滤不显示:根因
3.1 启动参数局部消费后丢弃
--cd 在 main 里读出来设了工作目录,但没存进全局「启动上下文」对象,选择器读不到。
3.2 远程模式跳过了上下文传递
--remote 分支里,CWD 被当成「远端的事情」没在本地上下文登记,选择器认为「没有 CWD」。
3.3 选择器状态未初始化
选择器组件初始化时没从上下文读 CWD,默认不显示过滤 UI。
3.4 参数解析顺序问题
--cd 紧跟 --remote,解析器把 --cd 当成 --remote 的参数而非独立 flag,值被吞。
四、最小可运行复现(参数未传递到选择器)
下面演示「--cd 被主流程消费但没存上下文」:
def parse_args_bad(argv):
ctx = {"remote": None, "cwd": None}
i = 0
while i < len(argv):
if argv[i] == "--remote":
ctx["remote"] = argv[i+1]; i += 2
elif argv[i] == "--cd":
# 错误:只打印/设了工作目录,没存进 ctx
print("设置工作目录:", argv[i+1])
i += 2
else:
i += 1
return ctx # cwd 始终是 None
if __name__ == "__main__":
ctx = parse_args_bad(["--remote", "h1", "--cd", "/projects/foo"])
print("选择器可读到的 cwd:", ctx["cwd"]) # None -> 过滤不显示
--cd 没存进上下文,选择器读到 None,过滤 UI 不显示(根因 3.1)。
五、解决方案一:启动上下文对象贯穿全程
把启动参数解析进一个「上下文对象」,全程共享,绝不局部丢弃:
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class LaunchContext:
remote: Optional[str] = None
cwd: Optional[str] = None
user: Optional[str] = None
def has_cwd(self) -> bool:
return bool(self.cwd)
def parse_args(argv) -> LaunchContext:
ctx = LaunchContext()
i = 0
while i < len(argv):
if argv[i] == "--remote" and i + 1 < len(argv):
ctx.remote = argv[i+1]; i += 2
elif argv[i] == "--cd" and i + 1 < len(argv):
ctx.cwd = argv[i+1]; i += 2 # 关键:存进上下文
else:
i += 1
return ctx
if __name__ == "__main__":
ctx = parse_args(["--remote", "h1", "--cd", "/projects/foo"])
print("选择器可读到的 cwd:", ctx.cwd) # /projects/foo ✅ 过滤可显示
LaunchContext 作为单一载体,--cd 存进去,选择器随时可读(解决 3.1/3.2)。
六、解决方案二:远程模式下也登记本地 CWD 视图
即便 --remote,--cd 也应作为「远端的工作目录」登记进上下文,选择器据此过滤远端的会话:
def build_resume_filter(ctx: LaunchContext):
"""根据启动上下文,决定 /resume 选择器显示哪些过滤。"""
filters = []
if ctx.has_cwd():
# 无论本地还是远程,cwd 都作为过滤维度
scope = f"remote:{ctx.remote}" if ctx.remote else "local"
filters.append({"type": "cwd", "value": ctx.cwd, "scope": scope})
if ctx.remote:
filters.append({"type": "remote", "value": ctx.remote})
return filters
if __name__ == "__main__":
ctx = parse_args(["--remote", "h1", "--cd", "/projects/foo"])
print("选择器过滤:", build_resume_filter(ctx))
# [{'type':'cwd','value':'/projects/foo','scope':'remote:h1'}, ...]
远程模式下 CWD 过滤依然登记(带 remote 作用域),选择器不缺选项(解决 3.2)。
七、解决方案三:选择器初始化时从上下文读取
选择器组件构造时主动从上下文取 CWD,有则渲染过滤 UI:
class ResumePicker:
def __init__(self, ctx: LaunchContext, sessions):
self.ctx = ctx
self.sessions = sessions
def visible_filters(self):
if self.ctx.has_cwd():
return ["按工作目录过滤", self.ctx.cwd]
return ["无 CWD 过滤"]
def filter_sessions(self):
if not self.ctx.has_cwd():
return self.sessions
return [s for s in self.sessions if s.get("cwd") == self.ctx.cwd]
if __name__ == "__main__":
ctx = parse_args(["--remote", "h1", "--cd", "/projects/foo"])
picker = ResumePicker(ctx, [
{"id": 1, "cwd": "/projects/foo"},
{"id": 2, "cwd": "/projects/bar"},
])
print("过滤 UI:", picker.visible_filters())
print("过滤后会话:", picker.filter_sessions()) # 只剩 cwd 匹配的
选择器从上下文读 CWD,有则显示过滤、按 CWD 筛(解决 3.3)。
八、参数解析健壮性
- 顺序无关:
--remote A --cd B与--cd B --remote A等价; - 不吞值:每个 flag 独立消费自己的下一个参数(第五节已处理);
- 默认值:
--cd缺省时取进程 cwd(如os.getcwd()),选择器仍有过滤; - 可观测:解析后打印上下文。
九、排查清单
「远程启动时恢复选择器不显示 CWD 过滤」,按下面排查:
--cd是否存进启动上下文?还是局部消费即弃(第五节,根因3.1);- 远程模式是否登记 CWD(第六节);
- 选择器是否从上下文读 CWD(第七节);
- 参数解析是否吞值?
--cd是否被当--remote的参数(第四节); --cd缺省是否有默认(第八节);- 多子功能是否共享同一上下文(呼应第133/105篇);
- 日志是否打印解析后的上下文;
- 本地 vs 远程行为是否一致(第六节 scope 区分)。
十、小结
「远程启动时 /resume 选择器不显示 CWD 过滤」的根因是**--cd 等启动上下文在解析后被局部消费、未存入可共享的上下文对象,后续子功能读不到**。通用修复:
- 上下文对象贯穿:解析进
LaunchContext,全程共享,绝不局部丢弃(第五节); - 远程也登记 CWD:远程模式下 CWD 带 remote 作用域登记,过滤不缺(第六节);
- 选择器读上下文:构造时取 CWD,有则渲染过滤并按其筛选(第七节);
- 解析健壮:顺序无关、不吞值、缺省有默认(第八节)。 一句话:启动参数不是「被某个功能一次性消费完就扔」的输入,而是「定义整个进程上下文状态」的种子,必须存进可共享对象供所有子功能读取。把启动上下文当成全局状态的第一公民,远程启动后 /resume 也能正确按
--cd过滤——这与第 133 篇配置继承、第 105 篇数据源聚合、第 112 篇跨设备同步,共同体现「上下文必须被完整传递与共享」。

更多推荐




所有评论(0)