mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Add Cursor support to setup import (#33426)
## What changed - Detect and import supported Cursor settings, sandbox permissions, MCP servers, project instructions, hooks, agents, commands, plugins, and recent chat sessions. - Update the `/import` flow to check Claude Code and Cursor, prompting for a source when both have importable data. - Add `migrationSource` to the app-server detect and import requests so each operation uses the selected adapter, while retaining `source` for import attribution and backwards compatibility. ## Testing - Add coverage for Cursor config conversion, hooks, plugins, session discovery and conversion, app-server imports, and TUI source selection. GitOrigin-RevId: a65a1511b6c1c2f9e3e0cfe4f816bb435807282e
This commit is contained in:
1 parent
0f2321f244
commit
1c4af96394
47 files changed
+2962
-247
No files matched your search
@@ -50,7 +50,6 @@ use super::service::ExternalAgentConfigMigrationItem as CoreMigrationItem;
|
||||
use super::service::ExternalAgentConfigMigrationItemType as CoreMigrationItemType;
|
||||
use super::service::ExternalAgentConfigService;
|
||||
use super::service::NamedMigration as CoreNamedMigration;
|
||||
use super::service::PendingPluginImport;
|
||||
use super::service::PluginImportOutcome;
|
||||
use super::service::record_import_error;
|
||||
use super::session_importer::ExternalAgentSessionImporter;
|
||||
@@ -117,8 +116,10 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
&self,
|
||||
params: ExternalAgentConfigDetectParams,
|
||||
) -> Result<ExternalAgentConfigDetectResponse, JSONRPCErrorError> {
|
||||
let items = self
|
||||
let migration_service = self
|
||||
.migration_service
|
||||
.with_migration_source(params.migration_source.as_deref());
|
||||
let items = migration_service
|
||||
.detect(ExternalAgentConfigDetectOptions {
|
||||
include_home: params.include_home,
|
||||
cwds: params.cwds,
|
||||
@@ -219,6 +220,9 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
let import_id = Uuid::new_v4().to_string();
|
||||
let analytics_source = params.source.clone().unwrap_or_default();
|
||||
let migration_service = self
|
||||
.migration_service
|
||||
.with_migration_source(params.migration_source.as_deref());
|
||||
let needs_runtime_refresh = migration_items_need_runtime_refresh(¶ms.migration_items);
|
||||
let has_migration_items = !params.migration_items.is_empty();
|
||||
let has_plugin_imports = params.migration_items.iter().any(|item| {
|
||||
@@ -228,8 +232,10 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
)
|
||||
});
|
||||
let (pending_session_imports, session_validation_result) =
|
||||
self.validate_pending_session_imports(¶ms);
|
||||
let import_outcome = self.import_external_agent_config(params).await;
|
||||
self.validate_pending_session_imports(¶ms, &migration_service);
|
||||
let import_outcome = self
|
||||
.import_external_agent_config(params, &migration_service)
|
||||
.await;
|
||||
if needs_runtime_refresh {
|
||||
self.config_processor.handle_config_mutation().await;
|
||||
}
|
||||
@@ -272,11 +278,12 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
}
|
||||
|
||||
let session_importer = self.session_importer.clone();
|
||||
let plugin_processor = self.clone();
|
||||
let outgoing = Arc::clone(&self.outgoing);
|
||||
let state_db = self.state_db.clone();
|
||||
let analytics_events_client = self.analytics_events_client.clone();
|
||||
let thread_manager = Arc::clone(&self.thread_manager);
|
||||
let session_metadata_mode = migration_service.session_metadata_mode();
|
||||
let plugin_migration_service = migration_service;
|
||||
let session_import_result = (!pending_session_imports.is_empty()).then(|| {
|
||||
CoreImportItemResult::new(
|
||||
CoreMigrationItemType::Sessions,
|
||||
@@ -291,7 +298,11 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
let session_imports = async move {
|
||||
let session_import_result = session_import_result?;
|
||||
let item_result = session_importer
|
||||
.import_sessions(pending_session_imports, session_import_result)
|
||||
.import_sessions(
|
||||
pending_session_imports,
|
||||
session_import_result,
|
||||
session_metadata_mode,
|
||||
)
|
||||
.await;
|
||||
send_import_progress(&session_progress_outgoing, &session_import_id, &item_result)
|
||||
.await;
|
||||
@@ -307,8 +318,11 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
pending_plugin_import.description.clone(),
|
||||
pending_plugin_import.cwd.clone(),
|
||||
);
|
||||
match plugin_processor
|
||||
.complete_pending_plugin_import(pending_plugin_import)
|
||||
match plugin_migration_service
|
||||
.import_plugins(
|
||||
pending_plugin_import.cwd.as_deref(),
|
||||
Some(pending_plugin_import.details),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(plugin_outcome) => {
|
||||
@@ -318,7 +332,7 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
record_import_error(
|
||||
&mut item_result,
|
||||
"plugin_import",
|
||||
error.message.clone(),
|
||||
error.to_string(),
|
||||
/*source*/ None,
|
||||
);
|
||||
}
|
||||
@@ -393,6 +407,7 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
fn validate_pending_session_imports(
|
||||
&self,
|
||||
params: &ExternalAgentConfigImportParams,
|
||||
migration_service: &ExternalAgentConfigService,
|
||||
) -> (Vec<CoreSessionMigration>, Option<CoreImportItemResult>) {
|
||||
let sessions = params
|
||||
.migration_items
|
||||
@@ -422,33 +437,31 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
let mut selected_session_paths = HashSet::new();
|
||||
let mut selected_sessions = Vec::new();
|
||||
for session in sessions {
|
||||
let canonical_path = match self
|
||||
.migration_service
|
||||
.external_agent_session_source_path(&session.path)
|
||||
{
|
||||
Ok(Some(canonical_path)) => canonical_path,
|
||||
Ok(None) => {
|
||||
record_import_error(
|
||||
&mut item_result,
|
||||
"session_missing",
|
||||
format!(
|
||||
"external agent session was not detected for import: {}",
|
||||
session.path.display()
|
||||
),
|
||||
Some(session.path.display().to_string()),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Err(err) => {
|
||||
record_import_error(
|
||||
&mut item_result,
|
||||
"session_source_path",
|
||||
err.to_string(),
|
||||
Some(session.path.display().to_string()),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let canonical_path =
|
||||
match migration_service.external_agent_session_source_path(&session.path) {
|
||||
Ok(Some(canonical_path)) => canonical_path,
|
||||
Ok(None) => {
|
||||
record_import_error(
|
||||
&mut item_result,
|
||||
"session_missing",
|
||||
format!(
|
||||
"external agent session was not detected for import: {}",
|
||||
session.path.display()
|
||||
),
|
||||
Some(session.path.display().to_string()),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
Err(err) => {
|
||||
record_import_error(
|
||||
&mut item_result,
|
||||
"session_source_path",
|
||||
err.to_string(),
|
||||
Some(session.path.display().to_string()),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if selected_session_paths.insert(canonical_path) {
|
||||
selected_sessions.push(session);
|
||||
}
|
||||
@@ -459,8 +472,9 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
async fn import_external_agent_config(
|
||||
&self,
|
||||
params: ExternalAgentConfigImportParams,
|
||||
migration_service: &ExternalAgentConfigService,
|
||||
) -> CoreImportOutcome {
|
||||
self.migration_service
|
||||
migration_service
|
||||
.import(
|
||||
params
|
||||
.migration_items
|
||||
@@ -558,19 +572,6 @@ impl ExternalAgentConfigRequestProcessor {
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn complete_pending_plugin_import(
|
||||
&self,
|
||||
pending_plugin_import: PendingPluginImport,
|
||||
) -> Result<PluginImportOutcome, JSONRPCErrorError> {
|
||||
self.migration_service
|
||||
.import_plugins(
|
||||
pending_plugin_import.cwd.as_deref(),
|
||||
Some(pending_plugin_import.details),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| internal_error(err.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_import_progress(
|
||||
|
||||
Reference in new issue
Block a user