@celestia-island/plana-types 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +38 -0
- package/bindings/FileAnchor.ts +3 -0
- package/bindings/engine.ts +277 -0
- package/bindings/enums.ts +31 -0
- package/bindings/httpTypes.ts +197 -0
- package/bindings/index.ts +47 -0
- package/bindings/mcp/aporia.ts +61 -0
- package/bindings/mcp/eleos.ts +18 -0
- package/bindings/mcp/epieikeia.ts +48 -0
- package/bindings/mcp/haplotes.ts +47 -0
- package/bindings/mcp/hubris.ts +41 -0
- package/bindings/mcp/index.ts +13 -0
- package/bindings/mcp/kalos.ts +47 -0
- package/bindings/mcp/neikos.ts +76 -0
- package/bindings/mcp/orexis.ts +64 -0
- package/bindings/mcp/philia.ts +57 -0
- package/bindings/mcp/polemos.ts +55 -0
- package/bindings/mcp/skemma.ts +58 -0
- package/bindings/mcp/skopeo.ts +56 -0
- package/bindings/mcp/webAutomation.ts +31 -0
- package/bindings/model.ts +240 -0
- package/bindings/package.json +16 -0
- package/bindings/region.ts +3 -0
- package/bindings/serde_json/JsonValue.ts +3 -0
- package/bindings/ws/agentLifecycle.ts +41 -0
- package/bindings/ws/auth.ts +15 -0
- package/bindings/ws/baseMessages.ts +7 -0
- package/bindings/ws/bridgeNetwork.ts +71 -0
- package/bindings/ws/core.ts +51 -0
- package/bindings/ws/fileBrowsing.ts +57 -0
- package/bindings/ws/handshake.ts +23 -0
- package/bindings/ws/industrial.ts +72 -0
- package/bindings/ws/knowledgeBase.ts +10 -0
- package/bindings/ws/layer2.ts +25 -0
- package/bindings/ws/llmProvider.ts +74 -0
- package/bindings/ws/logs.ts +11 -0
- package/bindings/ws/malkuth.ts +62 -0
- package/bindings/ws/noa.ts +17 -0
- package/bindings/ws/stateSync.ts +19 -0
- package/bindings/ws/systemUi.ts +5 -0
- package/bindings/ws/tasks.ts +6 -0
- package/bindings/ws/views.ts +163 -0
- package/bindings/ws/workspace.ts +11 -0
- package/bindings/ws/yolo.ts +32 -0
- package/examples/schema_dump.rs +51 -0
- package/package.json +6 -0
- package/pnpm-workspace.yaml +2 -0
- package/src/engine.rs +602 -0
- package/src/enums.rs +334 -0
- package/src/external_mcp.rs +132 -0
- package/src/http.rs +1077 -0
- package/src/identity.rs +160 -0
- package/src/lib.rs +1215 -0
- package/src/malkuth.rs +145 -0
- package/src/mcp/aporia.rs +272 -0
- package/src/mcp/eleos.rs +210 -0
- package/src/mcp/epieikeia.rs +194 -0
- package/src/mcp/haplotes.rs +310 -0
- package/src/mcp/hubris.rs +377 -0
- package/src/mcp/kalos.rs +251 -0
- package/src/mcp/mod.rs +23 -0
- package/src/mcp/neikos.rs +533 -0
- package/src/mcp/orexis.rs +493 -0
- package/src/mcp/philia.rs +267 -0
- package/src/mcp/polemos.rs +241 -0
- package/src/mcp/skemma.rs +442 -0
- package/src/mcp/skopeo.rs +282 -0
- package/src/mcp/web_automation.rs +122 -0
- package/src/model.rs +421 -0
- package/src/protocol/base_messages.rs +125 -0
- package/src/protocol/handshake.rs +364 -0
- package/src/protocol/jsonrpc.rs +888 -0
- package/src/protocol/mod.rs +10 -0
- package/src/rbac.rs +786 -0
- package/src/region.rs +362 -0
- package/src/tracing_helpers.rs +9 -0
- package/src/ws/agent/agent_lifecycle.rs +221 -0
- package/src/ws/agent/layer2.rs +126 -0
- package/src/ws/agent/mod.rs +9 -0
- package/src/ws/agent/state_sync.rs +111 -0
- package/src/ws/agent/tasks.rs +43 -0
- package/src/ws/agent/yolo.rs +161 -0
- package/src/ws/mod.rs +10 -0
- package/src/ws/services/auth.rs +99 -0
- package/src/ws/services/industrial.rs +647 -0
- package/src/ws/services/knowledge_base.rs +59 -0
- package/src/ws/services/llm_provider.rs +371 -0
- package/src/ws/services/mod.rs +7 -0
- package/src/ws/ui/bridge_network.rs +96 -0
- package/src/ws/ui/file_browsing.rs +88 -0
- package/src/ws/ui/logs.rs +55 -0
- package/src/ws/ui/mod.rs +11 -0
- package/src/ws/ui/noa.rs +105 -0
- package/src/ws/ui/system_ui.rs +27 -0
- package/src/ws/ui/views.rs +159 -0
- package/src/ws/ui/workspace.rs +73 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
use crate::enums::{ConsultationStatus, ContainerOpStatus};
|
|
2
|
+
|
|
3
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
4
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
5
|
+
pub struct ContainerListItem {
|
|
6
|
+
pub name: String,
|
|
7
|
+
pub image: String,
|
|
8
|
+
pub status: String,
|
|
9
|
+
pub id: String,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
13
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
14
|
+
pub struct ContainerListResult {
|
|
15
|
+
pub total_count: usize,
|
|
16
|
+
pub containers: Vec<ContainerListItem>,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
20
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
21
|
+
pub struct ContainerInfoResult {
|
|
22
|
+
pub container_id: String,
|
|
23
|
+
pub name: String,
|
|
24
|
+
pub image: String,
|
|
25
|
+
pub status: String,
|
|
26
|
+
pub running: bool,
|
|
27
|
+
pub exit_code: Option<i64>,
|
|
28
|
+
pub ip_address: String,
|
|
29
|
+
pub started_at: String,
|
|
30
|
+
pub ports: Vec<String>,
|
|
31
|
+
pub env: Vec<String>,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
35
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
36
|
+
pub struct ContainerStartResult {
|
|
37
|
+
pub container_id: String,
|
|
38
|
+
pub status: ContainerOpStatus,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
42
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
43
|
+
pub struct ContainerStopResult {
|
|
44
|
+
pub container_id: String,
|
|
45
|
+
pub status: ContainerOpStatus,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
49
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
50
|
+
pub struct ContainerRemoveResult {
|
|
51
|
+
pub container_id: String,
|
|
52
|
+
pub status: ContainerOpStatus,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
56
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
57
|
+
pub struct ContainerSnapshotResult {
|
|
58
|
+
pub container_id: String,
|
|
59
|
+
pub snapshot_id: String,
|
|
60
|
+
pub image_id: String,
|
|
61
|
+
pub image_name: String,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
65
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
66
|
+
pub struct VolumeInfo {
|
|
67
|
+
pub host_path: String,
|
|
68
|
+
pub container_path: String,
|
|
69
|
+
pub read_only: bool,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
73
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
74
|
+
pub struct ContainerCreateResult {
|
|
75
|
+
pub image: String,
|
|
76
|
+
pub container_id: String,
|
|
77
|
+
pub name: String,
|
|
78
|
+
pub network: String,
|
|
79
|
+
pub status: ContainerOpStatus,
|
|
80
|
+
pub volumes: Vec<VolumeInfo>,
|
|
81
|
+
#[serde(default)]
|
|
82
|
+
pub seccomp_enabled: bool,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
86
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
87
|
+
pub struct ContainerForkResult {
|
|
88
|
+
pub parent_container_id: String,
|
|
89
|
+
pub new_container_id: String,
|
|
90
|
+
pub branch_level: u32,
|
|
91
|
+
pub image: String,
|
|
92
|
+
pub fallback: bool,
|
|
93
|
+
pub status: ContainerOpStatus,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
97
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
98
|
+
pub struct ExecResult {
|
|
99
|
+
pub container_id: String,
|
|
100
|
+
pub command: String,
|
|
101
|
+
pub exit_code: Option<i64>,
|
|
102
|
+
pub output: String,
|
|
103
|
+
pub error: String,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
107
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
108
|
+
pub struct SidecarDeliverResult {
|
|
109
|
+
pub todo_id: String,
|
|
110
|
+
pub title: String,
|
|
111
|
+
pub target_badge: String,
|
|
112
|
+
pub status: ConsultationStatus,
|
|
113
|
+
pub metadata: std::collections::HashMap<String, String>,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
117
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
118
|
+
pub struct GitPushResult {
|
|
119
|
+
pub container_id: String,
|
|
120
|
+
pub branch: String,
|
|
121
|
+
pub remote: String,
|
|
122
|
+
pub commit_hash: Option<String>,
|
|
123
|
+
pub pushed: bool,
|
|
124
|
+
pub output: String,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Tool parameter structs (for .d.ts API signature generation) ──
|
|
128
|
+
|
|
129
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
130
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
131
|
+
pub struct NewContainerVolumeMount {
|
|
132
|
+
pub source: String,
|
|
133
|
+
pub target: String,
|
|
134
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
135
|
+
pub read_only: Option<bool>,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
139
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
140
|
+
pub struct NewContainerToolParams {
|
|
141
|
+
pub image: String,
|
|
142
|
+
pub name: Option<String>,
|
|
143
|
+
pub env: Option<std::collections::HashMap<String, String>>,
|
|
144
|
+
pub volumes: Option<Vec<NewContainerVolumeMount>>,
|
|
145
|
+
pub network: Option<String>,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
149
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
150
|
+
pub struct ContainerStartParams {
|
|
151
|
+
pub container_id: String,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
155
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
156
|
+
pub struct ContainerStopParams {
|
|
157
|
+
pub container_id: String,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
161
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
162
|
+
pub struct ContainerRemoveParams {
|
|
163
|
+
pub container_id: String,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
167
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
168
|
+
pub struct ContainerForkParams {
|
|
169
|
+
pub container_id: String,
|
|
170
|
+
pub name: Option<String>,
|
|
171
|
+
pub namespace_volume: Option<String>,
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
175
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
176
|
+
pub struct ContainerSnapshotParams {
|
|
177
|
+
pub container_id: String,
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
181
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
182
|
+
pub struct ContainerFilterCriteria {
|
|
183
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
184
|
+
pub label: Option<std::collections::HashMap<String, String>>,
|
|
185
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
186
|
+
pub name: Option<String>,
|
|
187
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
188
|
+
pub status: Option<Vec<String>>,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
192
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
193
|
+
pub struct ContainerListParams {
|
|
194
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
195
|
+
pub filter: Option<ContainerFilterCriteria>,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
199
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
200
|
+
pub struct ContainerInfoParams {
|
|
201
|
+
pub container_id: String,
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
205
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
206
|
+
pub struct ExecOnContainerParams {
|
|
207
|
+
pub command: String,
|
|
208
|
+
pub container_id: Option<String>,
|
|
209
|
+
pub target_badge: Option<String>,
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
213
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
214
|
+
pub struct GitPushBranchParams {
|
|
215
|
+
pub container_id: String,
|
|
216
|
+
pub commit_message: Option<String>,
|
|
217
|
+
pub branch: Option<String>,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
221
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
222
|
+
pub struct SidecarSpawnParams {
|
|
223
|
+
pub name: String,
|
|
224
|
+
pub cmd: Option<Vec<String>>,
|
|
225
|
+
pub language: Option<String>,
|
|
226
|
+
pub framing: Option<String>,
|
|
227
|
+
pub working_dir: Option<String>,
|
|
228
|
+
pub env: Option<std::collections::HashMap<String, String>>,
|
|
229
|
+
pub idle_timeout_secs: Option<u64>,
|
|
230
|
+
pub ready_pattern: Option<String>,
|
|
231
|
+
pub amphoreus_dir: Option<String>,
|
|
232
|
+
pub agent_folder: Option<String>,
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
236
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
237
|
+
pub struct SidecarSendParams {
|
|
238
|
+
pub name: String,
|
|
239
|
+
pub method: String,
|
|
240
|
+
#[ts(type = "Record<string, unknown> | null")]
|
|
241
|
+
pub params: Option<serde_json::Value>,
|
|
242
|
+
pub timeout_secs: Option<u64>,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
246
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
247
|
+
pub struct SidecarKillParams {
|
|
248
|
+
pub name: String,
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
252
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
253
|
+
pub struct ToolchainListParams {
|
|
254
|
+
pub amphoreus_dir: Option<String>,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
258
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
259
|
+
pub struct ToolchainEnsureParams {
|
|
260
|
+
pub profile_id: String,
|
|
261
|
+
pub amphoreus_dir: Option<String>,
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
265
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
266
|
+
pub struct WaitParams {
|
|
267
|
+
pub seconds: Option<u64>,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
271
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
272
|
+
pub struct CheckWaitParams {
|
|
273
|
+
pub handle: String,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
277
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
278
|
+
pub struct ToolchainProfileInfo {
|
|
279
|
+
pub id: String,
|
|
280
|
+
pub display_name: String,
|
|
281
|
+
pub source_image: String,
|
|
282
|
+
pub image_pulled: bool,
|
|
283
|
+
pub volume_ready: bool,
|
|
284
|
+
pub available_tools: Vec<String>,
|
|
285
|
+
pub supported_languages: Vec<String>,
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
289
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
290
|
+
pub struct ToolchainListResult {
|
|
291
|
+
pub profiles: Vec<ToolchainProfileInfo>,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
295
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
296
|
+
pub struct ToolchainVolumeSpec {
|
|
297
|
+
pub host_path: String,
|
|
298
|
+
pub container_path: String,
|
|
299
|
+
pub read_only: bool,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
303
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
304
|
+
pub struct ToolchainEnsureResult {
|
|
305
|
+
pub profile_id: String,
|
|
306
|
+
pub source_image: String,
|
|
307
|
+
pub container_image: String,
|
|
308
|
+
pub container_env: std::collections::HashMap<String, String>,
|
|
309
|
+
pub container_volumes: Vec<ToolchainVolumeSpec>,
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ts_rs::TS)]
|
|
313
|
+
#[ts(export, export_to = "mcp/neikos.ts")]
|
|
314
|
+
pub struct SidecarSendResult {
|
|
315
|
+
pub name: String,
|
|
316
|
+
pub sent: bool,
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#[cfg(test)]
|
|
320
|
+
mod tests {
|
|
321
|
+
use super::*;
|
|
322
|
+
use crate::enums::ContainerOpStatus;
|
|
323
|
+
use serde_json::json;
|
|
324
|
+
|
|
325
|
+
#[test]
|
|
326
|
+
fn container_list_result_round_trip() {
|
|
327
|
+
let r = ContainerListResult {
|
|
328
|
+
total_count: 2,
|
|
329
|
+
containers: vec![
|
|
330
|
+
ContainerListItem {
|
|
331
|
+
name: "web".into(),
|
|
332
|
+
image: "nginx:latest".into(),
|
|
333
|
+
status: "running".into(),
|
|
334
|
+
id: "abc123".into(),
|
|
335
|
+
},
|
|
336
|
+
ContainerListItem {
|
|
337
|
+
name: "db".into(),
|
|
338
|
+
image: "postgres:16".into(),
|
|
339
|
+
status: "exited".into(),
|
|
340
|
+
id: "def456".into(),
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
};
|
|
344
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
345
|
+
assert_eq!(v["total_count"], 2);
|
|
346
|
+
assert_eq!(v["containers"][0]["name"], "web");
|
|
347
|
+
let back: ContainerListResult = serde_json::from_value(v).unwrap();
|
|
348
|
+
assert_eq!(back.total_count, 2);
|
|
349
|
+
assert_eq!(back.containers[1].name, "db");
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#[test]
|
|
353
|
+
fn container_list_result_empty() {
|
|
354
|
+
let r = ContainerListResult {
|
|
355
|
+
total_count: 0,
|
|
356
|
+
containers: vec![],
|
|
357
|
+
};
|
|
358
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
359
|
+
assert_eq!(v["containers"], json!([]));
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
#[test]
|
|
363
|
+
fn container_info_result_with_exit_code() {
|
|
364
|
+
let r = ContainerInfoResult {
|
|
365
|
+
container_id: "cid".into(),
|
|
366
|
+
name: "test".into(),
|
|
367
|
+
image: "img".into(),
|
|
368
|
+
status: "exited".into(),
|
|
369
|
+
running: false,
|
|
370
|
+
exit_code: Some(0),
|
|
371
|
+
ip_address: "172.17.0.2".into(),
|
|
372
|
+
started_at: "2026-01-01T00:00:00Z".into(),
|
|
373
|
+
ports: vec!["8080:80".into()],
|
|
374
|
+
env: vec!["FOO=bar".into()],
|
|
375
|
+
};
|
|
376
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
377
|
+
assert_eq!(v["exit_code"], 0);
|
|
378
|
+
assert_eq!(v["running"], false);
|
|
379
|
+
let back: ContainerInfoResult = serde_json::from_value(v).unwrap();
|
|
380
|
+
assert_eq!(back.exit_code, Some(0));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
#[test]
|
|
384
|
+
fn container_info_result_no_exit_code() {
|
|
385
|
+
let r = ContainerInfoResult {
|
|
386
|
+
container_id: "cid".into(),
|
|
387
|
+
name: "test".into(),
|
|
388
|
+
image: "img".into(),
|
|
389
|
+
status: "running".into(),
|
|
390
|
+
running: true,
|
|
391
|
+
exit_code: None,
|
|
392
|
+
ip_address: "".into(),
|
|
393
|
+
started_at: "".into(),
|
|
394
|
+
ports: vec![],
|
|
395
|
+
env: vec![],
|
|
396
|
+
};
|
|
397
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
398
|
+
assert_eq!(v["exit_code"], serde_json::Value::Null);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
#[test]
|
|
402
|
+
fn container_op_status_enum_round_trip() {
|
|
403
|
+
for s in [
|
|
404
|
+
ContainerOpStatus::Created,
|
|
405
|
+
ContainerOpStatus::Running,
|
|
406
|
+
ContainerOpStatus::Stopped,
|
|
407
|
+
ContainerOpStatus::Removed,
|
|
408
|
+
ContainerOpStatus::Forked,
|
|
409
|
+
] {
|
|
410
|
+
let ser = serde_json::to_string(&s).unwrap();
|
|
411
|
+
let de: ContainerOpStatus = serde_json::from_str(&ser).unwrap();
|
|
412
|
+
assert_eq!(de, s);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
#[test]
|
|
417
|
+
fn container_start_result_round_trip() {
|
|
418
|
+
let r = ContainerStartResult {
|
|
419
|
+
container_id: "cid".into(),
|
|
420
|
+
status: ContainerOpStatus::Running,
|
|
421
|
+
};
|
|
422
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
423
|
+
// ContainerOpStatus serializes as PascalCase variant name.
|
|
424
|
+
assert_eq!(v["status"], "Running");
|
|
425
|
+
let back: ContainerStartResult = serde_json::from_value(v).unwrap();
|
|
426
|
+
assert_eq!(back.status, ContainerOpStatus::Running);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
#[test]
|
|
430
|
+
fn volume_info_round_trip() {
|
|
431
|
+
let v = VolumeInfo {
|
|
432
|
+
host_path: "/host/data".into(),
|
|
433
|
+
container_path: "/data".into(),
|
|
434
|
+
read_only: true,
|
|
435
|
+
};
|
|
436
|
+
let val = serde_json::to_value(&v).unwrap();
|
|
437
|
+
assert_eq!(val["read_only"], true);
|
|
438
|
+
let back: VolumeInfo = serde_json::from_value(val).unwrap();
|
|
439
|
+
assert!(back.read_only);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
#[test]
|
|
443
|
+
fn exec_result_round_trip() {
|
|
444
|
+
let r = ExecResult {
|
|
445
|
+
container_id: "cid".into(),
|
|
446
|
+
command: "ls -la".into(),
|
|
447
|
+
exit_code: Some(0),
|
|
448
|
+
output: "total 0\n".into(),
|
|
449
|
+
error: String::new(),
|
|
450
|
+
};
|
|
451
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
452
|
+
assert_eq!(v["exit_code"], 0);
|
|
453
|
+
let back: ExecResult = serde_json::from_value(v).unwrap();
|
|
454
|
+
assert_eq!(back.exit_code, Some(0));
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
#[test]
|
|
458
|
+
fn git_push_result_round_trip() {
|
|
459
|
+
let r = GitPushResult {
|
|
460
|
+
container_id: "cid".into(),
|
|
461
|
+
branch: "feature".into(),
|
|
462
|
+
remote: "origin".into(),
|
|
463
|
+
commit_hash: Some("abc123".into()),
|
|
464
|
+
pushed: true,
|
|
465
|
+
output: "Everything up-to-date".into(),
|
|
466
|
+
};
|
|
467
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
468
|
+
assert_eq!(v["pushed"], true);
|
|
469
|
+
assert_eq!(v["commit_hash"], "abc123");
|
|
470
|
+
let back: GitPushResult = serde_json::from_value(v).unwrap();
|
|
471
|
+
assert!(back.pushed);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
#[test]
|
|
475
|
+
fn container_create_result_seccomp_default() {
|
|
476
|
+
let r = ContainerCreateResult {
|
|
477
|
+
image: "img".into(),
|
|
478
|
+
container_id: "cid".into(),
|
|
479
|
+
name: "test".into(),
|
|
480
|
+
network: "bridge".into(),
|
|
481
|
+
status: ContainerOpStatus::Created,
|
|
482
|
+
volumes: vec![],
|
|
483
|
+
seccomp_enabled: false,
|
|
484
|
+
};
|
|
485
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
486
|
+
// seccomp_enabled has #[serde(default)] on deserialize but always
|
|
487
|
+
// serializes (no skip_serializing_if).
|
|
488
|
+
assert_eq!(v["seccomp_enabled"], false);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
#[test]
|
|
492
|
+
fn container_filter_criteria_all_optional_skip() {
|
|
493
|
+
let c = ContainerFilterCriteria {
|
|
494
|
+
label: None,
|
|
495
|
+
name: None,
|
|
496
|
+
status: None,
|
|
497
|
+
};
|
|
498
|
+
let v = serde_json::to_value(&c).unwrap();
|
|
499
|
+
// All fields use skip_serializing_if = "Option::is_none".
|
|
500
|
+
assert!(v.as_object().unwrap().is_empty());
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
#[test]
|
|
504
|
+
fn container_filter_criteria_with_values() {
|
|
505
|
+
let mut labels = std::collections::HashMap::new();
|
|
506
|
+
labels.insert("app".into(), "web".into());
|
|
507
|
+
let c = ContainerFilterCriteria {
|
|
508
|
+
label: Some(labels),
|
|
509
|
+
name: Some("web-*".into()),
|
|
510
|
+
status: Some(vec!["running".into()]),
|
|
511
|
+
};
|
|
512
|
+
let v = serde_json::to_value(&c).unwrap();
|
|
513
|
+
assert_eq!(v["name"], "web-*");
|
|
514
|
+
assert_eq!(v["label"]["app"], "web");
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
#[test]
|
|
518
|
+
fn toolchain_profile_info_round_trip() {
|
|
519
|
+
let r = ToolchainProfileInfo {
|
|
520
|
+
id: "rust-full".into(),
|
|
521
|
+
display_name: "Rust Toolchain".into(),
|
|
522
|
+
source_image: "rust:1.85".into(),
|
|
523
|
+
image_pulled: true,
|
|
524
|
+
volume_ready: true,
|
|
525
|
+
available_tools: vec!["cargo".into(), "rustc".into()],
|
|
526
|
+
supported_languages: vec!["rust".into()],
|
|
527
|
+
};
|
|
528
|
+
let v = serde_json::to_value(&r).unwrap();
|
|
529
|
+
assert_eq!(v["available_tools"][0], "cargo");
|
|
530
|
+
let back: ToolchainProfileInfo = serde_json::from_value(v).unwrap();
|
|
531
|
+
assert_eq!(back.available_tools.len(), 2);
|
|
532
|
+
}
|
|
533
|
+
}
|