Skip to content

[codex] persist Bash shell session state - #166

Merged
lyfmt merged 13 commits into
devfrom
feature/shell-env-state
Aug 10, 2026
Merged

[codex] persist Bash shell session state#166
lyfmt merged 13 commits into
devfrom
feature/shell-env-state

Conversation

@lyfmt

@lyfmt lyfmt commented Aug 7, 2026

Copy link
Copy Markdown
Owner

问题

bash 工具的每次调用都会启动独立进程,但此前没有会话级 shell 状态。用户在一条命令中执行 cd 后,后续 Bash 调用和 read/write/grep/glob 等文件工具仍从会话启动目录执行;登录 shell 中的 export、alias 和 function 也会在每次调用时重新初始化,无法稳定重放。

根因

Session header 没有区分固定的会话创建目录与可变化的 shell 工作目录,ToolRuntimeInvocation 也无法把当前 shell cwd 传到工具上下文。同时,BashTool 直接执行一次性 shell 进程,没有外部 snapshot、session env 脚本和命令结束后的 cwd 捕获机制。

解决方案

  • 新增 ShellState contract,并在 SessionHeader 中持久化当前 shell cwd;旧 session 自动回退到 header cwd,fork 和 child session 继承或初始化对应状态。
  • SessionManagerPort 暴露 shell 状态读写,持久 session 通过原子替换 JSONL header 更新 cwd,不修改历史 entry。
  • DefaultTurnExecutor 在上下文构建和工具调用前读取当前 shell cwd,通过 ToolRuntimeInvocation 注入 ToolUseContext,并在 Bash 执行后回写捕获到的 cwd。
  • 新增 ShellEnvironmentHarness:首次使用 login shell 生成 export/alias/function snapshot,后续调用重放 snapshot;按文件名加载 session env 脚本,并支持 LYPI_ENV_FILE 注入。
  • 更新 Bash 工具描述和 schema,向模型说明 cwd 持久化与环境重放语义,同时保留兼容的显式 cwd 执行覆盖。

权限分析、审批展示和风险判断仍只处理模型提供的原始 command;内部 wrapper 不改变现有权限决策输入。

验证

  • mvn test:12 个 reactor 模块全部通过;仅 2 个需要真实外部服务的端到端测试按既有条件跳过。
  • 定向测试:ContractSerializationTest 64 项、BashToolTest 34 项、ShellEnvironmentHarnessTest 6 项全部通过。
  • git diff --check origin/dev...HEAD 通过。

lyfmt added 13 commits August 7, 2026 21:59
对齐 Claude Code 一次性进程模型:每条命令独立 spawn,状态经外部文件继承。

- ShellState.cwd: Bash 命令尾 pwd -P 捕获,SessionManagerPort.updateShellState
  原子重写 JSONL 首行 header;ToolRuntimeInvocation.cwd 注入 ToolUseContext,
  Read/Write/Grep/Glob 默认目录随 cd 迁移;fork/child 继承 shellState
- ShellEnvironmentHarness: 首次 bash -lc dump export/alias/function 为
  snapshot(~/.lypi/shell-state/<sid>/),命中后 bash -c + source 重放,
  丢失回退 -lc;session env 目录 env/*.sh 按序 source(venv 激活跨命令生效);
  支持 LYPI_ENV_FILE 外部注入
- 权限分析与展示只看原始 command,wrapper 不进审批
- 显式 cwd 参数的命令绕过 harness,不污染会话状态
- BashTool 新增 description():向模型说明 cwd 跨命令持久(cd 后文件工具
  一并跟随)、环境经 snapshot 重放、export/source 不跨命令持久
- inputSchema 移除 cwd 入参;兼容期内仍接受(绝对/相对路径作一次性执行
  目录,走 harness 但不回写会话状态),resolveBashCwd 语义不变
- 清理 capturesShellCwd 死分支,所有命令统一经 harness 包装
Keep cwd deltas lexical under symlink workspace roots so runtime validation preserves them. Enable Bash alias expansion and force overwrite of precreated cwd and snapshot capture files.
@lyfmt
lyfmt marked this pull request as ready for review August 10, 2026 07:10
@lyfmt
lyfmt merged commit e1ff466 into dev Aug 10, 2026
4 checks passed
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.

1 participant