Start cloud threads with the local GitHub project (#60007)

## What changed

Pass the local project's GitHub origin to cloud prewarming so new cloud threads can provision a repository checkout. Preserve the attached local project when switching backends and resolve its origin for each thread start.

Normalize supported GitHub origins to credential-free HTTPS URLs and select a repository-specific cloud working directory. Unsupported origins retain the blank environment behavior. Keep project metadata outside the app-server wire protocol, and fix HTTP Git URL parsing so query strings and fragments cannot be mistaken for authority text.

## Testing

Add coverage for project routing, origin normalization and rejection, managed environment encoding, local project retention, and Git URL credential stripping.

GitOrigin-RevId: 5859769965faf060461ccc1cbb3fd48f8e2f2155
This commit is contained in:
Benjamin Carlsson
2026-11-06 23:00:38 +00:00
committed by copyberry
parent df769889c0
commit 7de8a0afc0
21 changed files with 491 additions and 15 deletions
+20
View File
@@ -19,6 +19,12 @@ use tokio::sync::oneshot;
/// Unsupported operations must return an explicit error; they must not claim success.
pub enum CloudOperation {
Request(Box<ClientRequest>),
/// Host project metadata stays on the private transport, outside the app-server wire.
StartProjectThread {
request_id: RequestId,
params: Box<codex_app_server_protocol::ThreadStartParams>,
project: codex_cloud_client::ProjectEnvironment,
},
SubmitUserMessage(Box<TurnStartParams>),
Notify(ClientNotification),
Resolve {
@@ -124,6 +130,20 @@ impl CloudClient {
}
impl CloudRequestHandle {
pub(crate) async fn start_project_thread(
&self,
request_id: RequestId,
params: codex_app_server_protocol::ThreadStartParams,
project: codex_cloud_client::ProjectEnvironment,
) -> io::Result<RequestResult> {
self.send(CloudOperation::StartProjectThread {
request_id,
params: Box::new(params),
project,
})
.await
}
/// Submit once with a stable message ID and saved thread settings. The server
/// starts or steers; an error can mean admission is unknown. Never auto-resend.
pub async fn submit_user_message(