Skip to main content

cc_switch_lib/deeplink/
mod.rs

1//! Deep link import functionality for CC Switch (CLI edition).
2//!
3//! Implements the `ccswitch://v1/import?...` protocol for importing resources.
4//! Currently supports importing provider configurations for Claude/Codex/Gemini/OpenCode/OpenClaw.
5
6mod parser;
7mod provider;
8mod utils;
9
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12
13pub use parser::parse_deeplink_url;
14pub use provider::import_provider_from_deeplink;
15
16/// Deep link import request model.
17///
18/// This mirrors the upstream request model to keep URL parsing compatible.
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(rename_all = "camelCase")]
21pub struct DeepLinkImportRequest {
22    pub version: String,
23    pub resource: String,
24
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub app: Option<String>,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub name: Option<String>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub enabled: Option<bool>,
31
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub homepage: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub endpoint: Option<String>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub api_key: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub icon: Option<String>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub model: Option<String>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub notes: Option<String>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub haiku_model: Option<String>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub sonnet_model: Option<String>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub opus_model: Option<String>,
50
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub content: Option<String>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub description: Option<String>,
55
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub apps: Option<String>,
58
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub repo: Option<String>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub directory: Option<String>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub branch: Option<String>,
65
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub config: Option<String>,
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub config_format: Option<String>,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub config_url: Option<String>,
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub usage_enabled: Option<bool>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub usage_script: Option<String>,
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub usage_api_key: Option<String>,
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub usage_base_url: Option<String>,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub usage_access_token: Option<String>,
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub usage_user_id: Option<String>,
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub usage_auto_interval: Option<u64>,
87
88    #[serde(skip)]
89    pub(crate) openclaw_config: Option<Value>,
90}