1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
4#[serde(rename_all = "snake_case")]
5pub enum CoverageLevel {
6 Explicit,
7 Passthrough,
8 Unsupported,
9 IntentionallyUnsupported,
10 Unknown,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14pub struct WrapperSurfaceScopedTargets {
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub platforms: Option<Vec<String>>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub target_triples: Option<Vec<String>>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct WrapperFlagCoverageV1 {
23 pub key: String,
24 pub level: CoverageLevel,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub note: Option<String>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub scope: Option<WrapperSurfaceScopedTargets>,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
32pub struct WrapperArgCoverageV1 {
33 pub name: String,
34 pub level: CoverageLevel,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub note: Option<String>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub scope: Option<WrapperSurfaceScopedTargets>,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42pub struct WrapperCommandCoverageV1 {
43 pub path: Vec<String>,
44 pub level: CoverageLevel,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub note: Option<String>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub scope: Option<WrapperSurfaceScopedTargets>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub flags: Option<Vec<WrapperFlagCoverageV1>>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub args: Option<Vec<WrapperArgCoverageV1>>,
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
56pub struct WrapperCoverageManifestV1 {
57 pub schema_version: u32,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub generated_at: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub wrapper_version: Option<String>,
62 pub coverage: Vec<WrapperCommandCoverageV1>,
63}
64
65pub fn wrapper_crate_version() -> &'static str {
66 env!("CARGO_PKG_VERSION")
67}
68
69pub fn wrapper_coverage_manifest() -> WrapperCoverageManifestV1 {
74 fn flag(key: &str, level: CoverageLevel) -> WrapperFlagCoverageV1 {
75 WrapperFlagCoverageV1 {
76 key: key.to_string(),
77 level,
78 note: None,
79 scope: None,
80 }
81 }
82
83 fn scope_targets(target_triples: &[&str]) -> WrapperSurfaceScopedTargets {
84 WrapperSurfaceScopedTargets {
85 platforms: None,
86 target_triples: Some(target_triples.iter().map(|t| t.to_string()).collect()),
87 }
88 }
89
90 fn command(
91 path: &[&str],
92 level: CoverageLevel,
93 note: Option<&str>,
94 flags: Vec<WrapperFlagCoverageV1>,
95 args: Vec<WrapperArgCoverageV1>,
96 ) -> WrapperCommandCoverageV1 {
97 WrapperCommandCoverageV1 {
98 path: path.iter().map(|s| s.to_string()).collect(),
99 level,
100 note: note.map(|s| s.to_string()),
101 scope: None,
102 flags: (!flags.is_empty()).then_some(flags),
103 args: (!args.is_empty()).then_some(args),
104 }
105 }
106
107 fn command_scoped(
108 path: &[&str],
109 level: CoverageLevel,
110 note: Option<&str>,
111 scope: WrapperSurfaceScopedTargets,
112 flags: Vec<WrapperFlagCoverageV1>,
113 args: Vec<WrapperArgCoverageV1>,
114 ) -> WrapperCommandCoverageV1 {
115 let mut out = command(path, level, note, flags, args);
116 out.scope = Some(scope);
117 out
118 }
119
120 WrapperCoverageManifestV1 {
121 schema_version: 1,
122 generated_at: None,
123 wrapper_version: None,
124 coverage: vec![
125 command(
127 &[],
128 CoverageLevel::Explicit,
129 None,
130 vec![
131 flag("--help", CoverageLevel::Explicit),
132 flag("--version", CoverageLevel::Explicit),
133 flag("--print", CoverageLevel::Explicit),
134 flag("--output-format", CoverageLevel::Explicit),
135 flag("--input-format", CoverageLevel::Explicit),
136 flag("--json-schema", CoverageLevel::Explicit),
137 flag("--model", CoverageLevel::Explicit),
138 flag("--allowedTools", CoverageLevel::Explicit),
139 flag("--disallowedTools", CoverageLevel::Explicit),
140 flag("--permission-mode", CoverageLevel::Explicit),
141 flag("--dangerously-skip-permissions", CoverageLevel::Explicit),
142 flag("--add-dir", CoverageLevel::Explicit),
143 flag("--mcp-config", CoverageLevel::Explicit),
144 flag("--strict-mcp-config", CoverageLevel::Explicit),
145 flag("--agent", CoverageLevel::Explicit),
146 flag("--agents", CoverageLevel::Explicit),
147 flag(
148 "--allow-dangerously-skip-permissions",
149 CoverageLevel::Explicit,
150 ),
151 flag("--append-system-prompt", CoverageLevel::Explicit),
152 flag("--betas", CoverageLevel::Explicit),
153 flag("--chrome", CoverageLevel::Explicit),
154 flag("--continue", CoverageLevel::Explicit),
155 flag("--debug", CoverageLevel::Explicit),
156 flag("--debug-file", CoverageLevel::Explicit),
157 flag("--disable-slash-commands", CoverageLevel::Explicit),
158 flag("--fallback-model", CoverageLevel::Explicit),
159 flag("--file", CoverageLevel::Explicit),
160 flag("--fork-session", CoverageLevel::Explicit),
161 flag("--from-pr", CoverageLevel::Explicit),
162 flag("--ide", CoverageLevel::Explicit),
163 flag("--include-partial-messages", CoverageLevel::Explicit),
164 flag("--max-budget-usd", CoverageLevel::Explicit),
165 flag("--mcp-debug", CoverageLevel::Explicit),
166 flag("--no-chrome", CoverageLevel::Explicit),
167 flag("--no-session-persistence", CoverageLevel::Explicit),
168 flag("--plugin-dir", CoverageLevel::Explicit),
169 flag("--replay-user-messages", CoverageLevel::Explicit),
170 flag("--resume", CoverageLevel::Explicit),
171 flag("--session-id", CoverageLevel::Explicit),
172 flag("--setting-sources", CoverageLevel::Explicit),
173 flag("--settings", CoverageLevel::Explicit),
174 flag("--system-prompt", CoverageLevel::Explicit),
175 flag("--tools", CoverageLevel::Explicit),
176 flag("--verbose", CoverageLevel::Explicit),
177 ],
178 vec![],
179 ),
180 command_scoped(
182 &["install"],
183 CoverageLevel::IntentionallyUnsupported,
184 Some("Claude Code installation is out of scope for this wrapper."),
185 scope_targets(&["win32-x64"]),
186 vec![WrapperFlagCoverageV1 {
187 key: "--force".to_string(),
188 level: CoverageLevel::IntentionallyUnsupported,
189 note: Some(
190 "Claude Code installation is out of scope for this wrapper.".to_string(),
191 ),
192 scope: None,
193 }],
194 vec![],
195 ),
196 command(&["update"], CoverageLevel::Explicit, None, vec![], vec![]),
197 command(&["doctor"], CoverageLevel::Explicit, None, vec![], vec![]),
198 command(
199 &["setup-token"],
200 CoverageLevel::Explicit,
201 None,
202 vec![],
203 vec![],
204 ),
205 command(&["mcp"], CoverageLevel::Explicit, None, vec![], vec![]),
207 command(
208 &["mcp", "list"],
209 CoverageLevel::Explicit,
210 None,
211 vec![],
212 vec![],
213 ),
214 command_scoped(
215 &["mcp", "get"],
216 CoverageLevel::Explicit,
217 None,
218 scope_targets(&["win32-x64"]),
219 vec![],
220 vec![WrapperArgCoverageV1 {
221 name: "name".to_string(),
222 level: CoverageLevel::Explicit,
223 note: None,
224 scope: None,
225 }],
226 ),
227 command_scoped(
228 &["mcp", "add"],
229 CoverageLevel::Explicit,
230 None,
231 scope_targets(&["win32-x64"]),
232 vec![
233 flag("--scope", CoverageLevel::Explicit),
234 flag("--transport", CoverageLevel::Explicit),
235 flag("--env", CoverageLevel::Explicit),
236 flag("--header", CoverageLevel::Explicit),
237 ],
238 vec![
239 WrapperArgCoverageV1 {
240 name: "name".to_string(),
241 level: CoverageLevel::Explicit,
242 note: None,
243 scope: None,
244 },
245 WrapperArgCoverageV1 {
246 name: "commandOrUrl".to_string(),
247 level: CoverageLevel::Explicit,
248 note: None,
249 scope: None,
250 },
251 ],
252 ),
253 command_scoped(
254 &["mcp", "remove"],
255 CoverageLevel::Explicit,
256 None,
257 scope_targets(&["win32-x64"]),
258 vec![flag("--scope", CoverageLevel::Explicit)],
259 vec![WrapperArgCoverageV1 {
260 name: "name".to_string(),
261 level: CoverageLevel::Explicit,
262 note: None,
263 scope: None,
264 }],
265 ),
266 command_scoped(
267 &["mcp", "add-json"],
268 CoverageLevel::Explicit,
269 None,
270 scope_targets(&["win32-x64"]),
271 vec![flag("--scope", CoverageLevel::Explicit)],
272 vec![
273 WrapperArgCoverageV1 {
274 name: "name".to_string(),
275 level: CoverageLevel::Explicit,
276 note: None,
277 scope: None,
278 },
279 WrapperArgCoverageV1 {
280 name: "json".to_string(),
281 level: CoverageLevel::Explicit,
282 note: None,
283 scope: None,
284 },
285 ],
286 ),
287 command(
288 &["mcp", "reset-project-choices"],
289 CoverageLevel::Explicit,
290 None,
291 vec![],
292 vec![],
293 ),
294 command_scoped(
295 &["mcp", "serve"],
296 CoverageLevel::Explicit,
297 None,
298 scope_targets(&["win32-x64"]),
299 vec![],
300 vec![],
301 ),
302 command_scoped(
303 &["mcp", "add-from-claude-desktop"],
304 CoverageLevel::Explicit,
305 None,
306 scope_targets(&["win32-x64"]),
307 vec![flag("--scope", CoverageLevel::Explicit)],
308 vec![],
309 ),
310 command(&["plugin"], CoverageLevel::Explicit, None, vec![], vec![]),
312 command_scoped(
313 &["plugin", "list"],
314 CoverageLevel::Explicit,
315 None,
316 scope_targets(&["win32-x64"]),
317 vec![
318 flag("--available", CoverageLevel::Explicit),
319 flag("--json", CoverageLevel::Explicit),
320 ],
321 vec![],
322 ),
323 command_scoped(
324 &["plugin", "enable"],
325 CoverageLevel::Explicit,
326 None,
327 scope_targets(&["win32-x64"]),
328 vec![flag("--scope", CoverageLevel::Explicit)],
329 vec![WrapperArgCoverageV1 {
330 name: "plugin".to_string(),
331 level: CoverageLevel::Explicit,
332 note: None,
333 scope: None,
334 }],
335 ),
336 command_scoped(
337 &["plugin", "disable"],
338 CoverageLevel::Explicit,
339 None,
340 scope_targets(&["win32-x64"]),
341 vec![
342 flag("--all", CoverageLevel::Explicit),
343 flag("--scope", CoverageLevel::Explicit),
344 ],
345 vec![],
346 ),
347 command_scoped(
348 &["plugin", "install"],
349 CoverageLevel::Explicit,
350 None,
351 scope_targets(&["win32-x64"]),
352 vec![flag("--scope", CoverageLevel::Explicit)],
353 vec![],
354 ),
355 command_scoped(
356 &["plugin", "uninstall"],
357 CoverageLevel::Explicit,
358 None,
359 scope_targets(&["win32-x64"]),
360 vec![flag("--scope", CoverageLevel::Explicit)],
361 vec![],
362 ),
363 command_scoped(
364 &["plugin", "update"],
365 CoverageLevel::Explicit,
366 None,
367 scope_targets(&["win32-x64"]),
368 vec![flag("--scope", CoverageLevel::Explicit)],
369 vec![WrapperArgCoverageV1 {
370 name: "plugin".to_string(),
371 level: CoverageLevel::Explicit,
372 note: None,
373 scope: None,
374 }],
375 ),
376 command_scoped(
377 &["plugin", "validate"],
378 CoverageLevel::Explicit,
379 None,
380 scope_targets(&["win32-x64"]),
381 vec![],
382 vec![WrapperArgCoverageV1 {
383 name: "path".to_string(),
384 level: CoverageLevel::Explicit,
385 note: None,
386 scope: None,
387 }],
388 ),
389 command_scoped(
390 &["plugin", "manifest"],
391 CoverageLevel::Explicit,
392 None,
393 scope_targets(&["linux-x64", "darwin-arm64"]),
394 vec![],
395 vec![],
396 ),
397 command_scoped(
398 &["plugin", "manifest", "marketplace"],
399 CoverageLevel::Explicit,
400 None,
401 scope_targets(&["linux-x64", "darwin-arm64"]),
402 vec![],
403 vec![],
404 ),
405 command(
406 &["plugin", "marketplace"],
407 CoverageLevel::Explicit,
408 None,
409 vec![],
410 vec![],
411 ),
412 command_scoped(
413 &["plugin", "marketplace", "add"],
414 CoverageLevel::Explicit,
415 None,
416 scope_targets(&["win32-x64"]),
417 vec![],
418 vec![WrapperArgCoverageV1 {
419 name: "source".to_string(),
420 level: CoverageLevel::Explicit,
421 note: None,
422 scope: None,
423 }],
424 ),
425 command_scoped(
426 &["plugin", "marketplace", "list"],
427 CoverageLevel::Explicit,
428 None,
429 scope_targets(&["win32-x64"]),
430 vec![flag("--json", CoverageLevel::Explicit)],
431 vec![],
432 ),
433 command_scoped(
434 &["plugin", "marketplace", "remove"],
435 CoverageLevel::Explicit,
436 None,
437 scope_targets(&["win32-x64"]),
438 vec![],
439 vec![],
440 ),
441 command_scoped(
442 &["plugin", "marketplace", "repo"],
443 CoverageLevel::Explicit,
444 None,
445 scope_targets(&["linux-x64", "darwin-arm64"]),
446 vec![],
447 vec![],
448 ),
449 command_scoped(
450 &["plugin", "marketplace", "update"],
451 CoverageLevel::Explicit,
452 None,
453 scope_targets(&["win32-x64"]),
454 vec![],
455 vec![],
456 ),
457 ],
458 }
459}