The bash command parser in exec_policy was failing to parse commands
with concatenated flag-value patterns like `-g"*.py"` (no space between
flag and quoted value). This caused policy rules like
`prefix_rule(pattern=["rg"])` to not match commands such as `rg -n "foo"
-g"*.py"`.
When tree-sitter-bash parses `-g"*.py"`, it creates a "concatenation"
node containing a word (`-g`) and a string (`"*.py"`). The parser
previously rejected any node type not in the ALLOWED_KINDS list, causing
the entire command parsing to fail and fall back to matching against the
wrapped `bash -lc` command instead of the inner command.
This change:
- Adds "concatenation" to ALLOWED_KINDS in
try_parse_word_only_commands_sequence
- Adds handling for concatenation nodes in parse_plain_command_from_node
that recursively extracts and joins word/string/raw_string children
- Adds test cases for concatenated flag patterns with double and single
quotes
Fixes#8394
## Problem
The introduction of `notify_sandbox_state_change()` in #7112 caused a
regression where the blocking call in `Session::new()` waits for all MCP
servers to fully initialize before returning. This prevents the TUI
event loop from starting, resulting in `McpStartupUpdateEvent` messages
being emitted but never consumed or displayed. As a result, the app
appears to hang during startup, and users do not see the expected
"Booting MCP server: {name}" status line.
Issue: [#7827](https://github.com/openai/codex/issues/7827)
## Solution
This change moves sandbox state notification into each MCP server's
background initialization task. The notification is sent immediately
after the server transitions to the Ready state. This approach:
- Avoids blocking `Session::new()`, allowing the TUI event loop to start
promptly.
- Ensures each MCP server receives its sandbox state before handling any
tool calls.
- Restores the display of "Booting MCP server" status lines during
startup.
## Key Changes
- Added `ManagedClient::notify_sandbox_state()` method.
- Passed sandbox_state to `McpConnectionManager::initialize()`.
- Sends sandbox state notification in the background task after the
server reaches Ready status.
- Removed blocking notify_sandbox_state_change() methods.
- Added a chatwidget snapshot test for the "Booting MCP server" status
line.
## Regression Details
Regression was bisected to #7112, which introduced the blocking
behavior.
---------
Co-authored-by: Michael Bolin <bolinfest@gmail.com>
Co-authored-by: Michael Bolin <mbolin@openai.com>