feat(session-create): expose terminal_launch_args on sys_session_create - #4345
Conversation
sys_session_create did not forward terminal_launch_args, so top-level sessions launched by agent_id/config_path could not declare a native- terminal bypass stance. The server already accepts and validates the field on BOTH create paths (JSON SessionCreateRequest.model_validate and multipart SessionCreateMetadata via _parse_session_create_metadata -> _validate_terminal_launch_args); only the tool surface omitted it. Effect: a headless cursor-native worker uploaded via config_path ran WITHOUT --yolo even with executor.config.yolo: true, because the --yolo auto-derivation (_derive_terminal_launch_args_from_spec) only fires for NAMED sub-agent creates (body.sub_agent_name set), not for top-level/config_path sessions. The worker then stalled on cursor- agent's in-terminal approval prompts, surfaced as web elicitation cards that a headless run has no human to answer. Fix (surgical, additive): add a terminal_launch_args param to the sys_session_create schema and forward it verbatim into the JSON body (_build_session_create_body) and the multipart metadata (_upload_config_bundle). The server keeps owning validation/bounds- checking; this restores UI<->API parity (the web permission-mode selector already sets body.terminal_launch_args for top-level sessions). Adds a regression test asserting the field reaches the create body.
|
@javiermontescarrera Thanks for the PR! It doesn't reference an issue yet. We require an issue for every PR, so the work can be prioritized before it's reviewed. Add one to the description:
No issue exists for this yet? Open one first, then reference it. That's how we track what's worth doing, and it's usually quicker than it sounds. Note a reference has to point at an issue: naming another PR doesn't count. The only exceptions are changes with no user-visible behaviour: pure Refactor / chore, Docs, or Test / CI work. If that's genuinely what this is, check that box under Type of change. Anything that fixes a bug, adds a feature, or changes the UI needs an issue, even when it also touches docs or tests. See CONTRIBUTING.md for the full policy. No action is taken beyond this comment. |
Problem
sys_session_createdid not forwardterminal_launch_args, so top-level sessions launched viaagent_idorconfig_pathcould not declare a native-terminal bypass stance. A headlesscursor-nativeworker uploaded viaconfig_paththerefore ran without--yoloeven when its bundle declaredexecutor.config.yolo: true, and stalled on cursor-agent's in-terminal approval prompts — surfaced as web elicitation cards that no human is present to answer.Root cause
The
--yoloauto-derivation (_derive_terminal_launch_args_from_spec) only fires for named sub-agent creates (body.sub_agent_nameset) — not for top-levelconfig_path/agent_idsessions (sub_agent_nameis null). Those take theelsebranch (orchestration.py:5842) which reads caller-suppliedbody.terminal_launch_args. The bundle'syolo: trueis silently ignored for top-level sessions — by design (a caller cannot inject launch wiring by smuggling args through a spawn body; the flat-list + bounds-check is the security boundary).So the bypass stance must be declared at the launch call, not derived from an uploaded bundle — exactly what the web UI's permission-mode selector already does for top-level sessions.
Fix (surgical, additive)
The server already accepts and validates
terminal_launch_argson both create paths:SessionCreateRequest.model_validate_parse_session_create_metadata→SessionCreateMetadata→_validate_terminal_launch_argsThe only gap was the tool surface. This PR:
terminal_launch_argsparam to thesys_session_createschema._build_session_create_body) and the multipart metadata (_upload_config_bundle).body.terminal_launch_argsfor top-level sessions; the programmatic API now can too).Why not derive
--yolofor top-level sessions instead?That would collapse the security boundary: any uploaded bundle with
yolo: truewould auto-bypass approvals, and it would be a cursor-native special case. Declaring the stance at the (trusted) call site is the correct layer separation and generalizes across cursor/codex/claude-native.Tests
test_sys_session_create_forwards_terminal_launch_args— asserts the field reaches the create body verbatim.sys_session_createtests pass (no regression).