[codex] Use local environment for user shell commands (#28163)

## Why

User shell commands still read the legacy turn cwd and session shell
even though execution context is now owned by selected turn
environments. App-server also defines `thread/shellCommand` as a
local-host escape hatch, so it must use an available local environment
even when a remote environment is primary.

## What changed

- Add `ResolvedTurnEnvironments::local()` to find the selected local
environment.
- Resolve the user shell command cwd and shell from that local
`TurnEnvironment`.
- Emit the standard `shell is unavailable in this session` error when no
selected local environment or resolved local shell is available.
- Add an integration test covering `/shell` without a local environment.

## Test plan

- `just test -p codex-core
user_shell_command_without_local_environment_emits_error`
This commit is contained in:
pakrym-oai
2026-06-15 21:55:20 -07:00
committed by GitHub
Unverified
parent e752f7b4ae
commit 1e015884c5
6 changed files with 101 additions and 30 deletions
+8 -4
View File
@@ -439,7 +439,7 @@ async fn warm_plugins_and_skills_for_session_init(
config: Arc<Config>,
plugins_manager: Arc<PluginsManager>,
skills_manager: Arc<SkillsManager>,
turn_environments: TurnEnvironmentSnapshot,
turn_environments: &TurnEnvironmentSnapshot,
) -> Vec<SkillError> {
let fs = turn_environments.primary_filesystem();
let plugins_input = config.plugins_config_input();
@@ -829,7 +829,7 @@ impl Session {
Arc::clone(&config),
Arc::clone(&plugins_manager),
Arc::clone(&skills_manager),
resolved_environments,
&resolved_environments,
)
.instrument(info_span!(
"session_init.plugin_skill_warmup",
@@ -913,8 +913,12 @@ impl Session {
(None, None)
};
let hooks =
build_hooks_for_config(&config, plugins_manager.as_ref(), &default_shell).await;
let hooks = build_hooks_for_config(
&config,
plugins_manager.as_ref(),
resolved_environments.single_local_environment(),
)
.await;
for warning in hooks.startup_warnings() {
post_session_configured_events.push(Event {
id: INITIAL_SUBMIT_ID.to_owned(),