1use serde::{Deserialize, Serialize};
2use serde_json::{Map, Value};
3
4#[derive(Debug, Clone, Default, Serialize, Deserialize)]
5pub struct RepositoryFingerprint {
6 pub remote_url: Option<String>,
7 pub host: Option<String>,
8 pub owner: Option<String>,
9 pub repo_name: Option<String>,
10 pub default_branch: Option<String>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct CheckoutBinding {
15 pub project_id: String,
16 pub local_root: Option<String>,
17 pub branch: Option<String>,
18 pub last_commit: Option<String>,
19 pub client_label: Option<String>,
20 pub last_sync: Option<String>,
21}
22
23impl Default for CheckoutBinding {
24 fn default() -> Self {
25 Self {
26 project_id: "pending".to_string(),
27 local_root: None,
28 branch: None,
29 last_commit: None,
30 client_label: None,
31 last_sync: None,
32 }
33 }
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ProjectResolutionRequest {
38 pub fingerprint: RepositoryFingerprint,
39 pub suggested_slug: Option<String>,
40 #[serde(rename = "checkout_binding", alias = "workspace_binding")]
41 pub checkout_binding: Option<CheckoutBinding>,
42 pub project_metadata: Option<ProjectMetadataEnvelope>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct ProjectRecord {
47 pub project_id: String,
48 pub slug: String,
49 pub fingerprint: Option<RepositoryFingerprint>,
50 pub created_at: String,
51 pub updated_at: String,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct ProjectResolutionResponse {
56 pub project: ProjectRecord,
57 #[serde(rename = "checkout_bound", alias = "workspace_bound")]
58 pub checkout_bound: bool,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct ToolDefinition {
63 pub name: String,
64 pub description: String,
65 #[serde(rename = "inputSchema")]
66 pub input_schema: Value,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct ToolListResponse {
71 pub tools: Vec<ToolDefinition>,
72 pub total: usize,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct ToolCallRequest {
77 pub name: String,
78 pub arguments: Map<String, Value>,
79 pub project_id: Option<String>,
80 pub project_slug: Option<String>,
81 pub repository_fingerprint: Option<RepositoryFingerprint>,
82 #[serde(rename = "checkout_binding", alias = "workspace_binding")]
83 pub checkout_binding: Option<CheckoutBinding>,
84 pub project_metadata: Option<ProjectMetadataEnvelope>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct ToolCallResponse {
89 pub result: Value,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct ServerConnection {
94 pub endpoint: String,
95 pub token: String,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct ProjectMetadataEnvelope {
100 pub schema_version: u32,
101 pub summary: ProjectMetadataSummary,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct ProjectMetadataSummary {
106 pub total_file_count: u64,
107 pub source_file_count: u64,
108 pub markers: Vec<String>,
109 pub languages: Vec<ProjectLanguageStat>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct ProjectLanguageStat {
114 pub language: String,
115 pub file_count: u64,
116}
117
118#[derive(Debug, Clone)]
119pub struct ProjectContext {
120 pub project_slug: String,
121 pub project_root: String,
122 pub fingerprint: RepositoryFingerprint,
123 pub checkout_binding: CheckoutBinding,
124 pub project_metadata: Option<ProjectMetadataEnvelope>,
125}
126
127pub type RepositoryContext = ProjectContext;
128pub type WorkspaceBinding = CheckoutBinding;
129#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct TelemetryIngestRequest {
133 pub tool_name: String,
134 pub tokens_original: i64,
135 pub tokens_saved: i64,
136 pub duration_ms: i64,
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub mode: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub repository_fingerprint: Option<RepositoryFingerprint>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub checkout_binding: Option<CheckoutBinding>,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub project_slug: Option<String>,
145}