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 flag_note(key: &str, level: CoverageLevel, note: &str) -> WrapperFlagCoverageV1 {
84 WrapperFlagCoverageV1 {
85 key: key.to_string(),
86 level,
87 note: Some(note.to_string()),
88 scope: None,
89 }
90 }
91
92 fn arg(name: &str, level: CoverageLevel) -> WrapperArgCoverageV1 {
93 WrapperArgCoverageV1 {
94 name: name.to_string(),
95 level,
96 note: None,
97 scope: None,
98 }
99 }
100
101 fn arg_note(name: &str, level: CoverageLevel, note: &str) -> WrapperArgCoverageV1 {
102 WrapperArgCoverageV1 {
103 name: name.to_string(),
104 level,
105 note: Some(note.to_string()),
106 scope: None,
107 }
108 }
109
110 fn command(
111 path: &[&str],
112 level: CoverageLevel,
113 note: Option<&str>,
114 flags: Vec<WrapperFlagCoverageV1>,
115 args: Vec<WrapperArgCoverageV1>,
116 ) -> WrapperCommandCoverageV1 {
117 WrapperCommandCoverageV1 {
118 path: path.iter().map(|s| s.to_string()).collect(),
119 level,
120 note: note.map(|s| s.to_string()),
121 scope: None,
122 flags: (!flags.is_empty()).then_some(flags),
123 args: (!args.is_empty()).then_some(args),
124 }
125 }
126
127 WrapperCoverageManifestV1 {
128 schema_version: 1,
129 generated_at: None,
130 wrapper_version: None,
131 coverage: vec![
132 command(
134 &[],
135 CoverageLevel::Explicit,
136 None,
137 vec![
138 flag("--help", CoverageLevel::Explicit),
139 flag("--version", CoverageLevel::Explicit),
140 flag("--model", CoverageLevel::Explicit),
141 flag("--image", CoverageLevel::Explicit),
142 flag_note("--add-dir", CoverageLevel::Explicit, "capability-guarded"),
143 flag_note(
144 "--config",
145 CoverageLevel::Passthrough,
146 "Generic config overrides are forwarded as strings; keys are not typed/validated by the wrapper.",
147 ),
148 flag_note(
149 "--enable",
150 CoverageLevel::Passthrough,
151 "Generic feature toggles are forwarded as strings; individual feature flags are not typed by the wrapper.",
152 ),
153 flag_note(
154 "--disable",
155 CoverageLevel::Passthrough,
156 "Generic feature toggles are forwarded as strings; individual feature flags are not typed by the wrapper.",
157 ),
158 flag("--profile", CoverageLevel::Explicit),
159 flag("--cd", CoverageLevel::Explicit),
160 flag("--ask-for-approval", CoverageLevel::Explicit),
161 flag("--sandbox", CoverageLevel::Explicit),
162 flag("--full-auto", CoverageLevel::Explicit),
163 flag(
164 "--dangerously-bypass-approvals-and-sandbox",
165 CoverageLevel::Explicit,
166 ),
167 flag("--local-provider", CoverageLevel::Explicit),
168 flag("--oss", CoverageLevel::Explicit),
169 flag("--search", CoverageLevel::Explicit),
170 ],
171 vec![],
172 ),
173 command(
175 &["exec"],
176 CoverageLevel::Explicit,
177 None,
178 vec![
179 flag("--color", CoverageLevel::Explicit),
180 flag("--skip-git-repo-check", CoverageLevel::Explicit),
181 flag("--json", CoverageLevel::Explicit),
182 flag("--output-last-message", CoverageLevel::Explicit),
183 flag_note(
184 "--output-schema",
185 CoverageLevel::Explicit,
186 "capability-guarded",
187 ),
188 ],
189 vec![arg("PROMPT", CoverageLevel::Explicit)],
190 ),
191 command(
193 &["exec", "resume"],
194 CoverageLevel::Explicit,
195 None,
196 vec![
197 flag("--json", CoverageLevel::Explicit),
198 flag("--skip-git-repo-check", CoverageLevel::Explicit),
199 flag("--last", CoverageLevel::Explicit),
200 flag("--all", CoverageLevel::Explicit),
201 ],
202 vec![
203 arg("PROMPT", CoverageLevel::Explicit),
204 arg("SESSION_ID", CoverageLevel::Explicit),
205 ],
206 ),
207 command(
209 &["apply"],
210 CoverageLevel::Explicit,
211 None,
212 vec![],
213 vec![arg("TASK_ID", CoverageLevel::Explicit)],
214 ),
215 command(
217 &["cloud", "diff"],
218 CoverageLevel::Explicit,
219 None,
220 vec![flag("--attempt", CoverageLevel::Explicit)],
221 vec![arg("TASK_ID", CoverageLevel::Explicit)],
222 ),
223 command(
224 &["cloud", "apply"],
225 CoverageLevel::Explicit,
226 None,
227 vec![flag("--attempt", CoverageLevel::Explicit)],
228 vec![arg("TASK_ID", CoverageLevel::Explicit)],
229 ),
230 command(
231 &["cloud", "status"],
232 CoverageLevel::Explicit,
233 None,
234 vec![],
235 vec![arg("TASK_ID", CoverageLevel::Explicit)],
236 ),
237 command(
238 &["cloud", "list"],
239 CoverageLevel::Explicit,
240 None,
241 vec![
242 flag("--cursor", CoverageLevel::Explicit),
243 flag("--env", CoverageLevel::Explicit),
244 flag("--json", CoverageLevel::Explicit),
245 flag("--limit", CoverageLevel::Explicit),
246 ],
247 vec![],
248 ),
249 command(
250 &["cloud", "exec"],
251 CoverageLevel::Explicit,
252 None,
253 vec![
254 flag("--env", CoverageLevel::Explicit),
255 flag("--attempts", CoverageLevel::Explicit),
256 flag("--branch", CoverageLevel::Explicit),
257 ],
258 vec![arg("QUERY", CoverageLevel::Explicit)],
259 ),
260 command(
262 &["login"],
263 CoverageLevel::Explicit,
264 None,
265 vec![
266 flag_note("--mcp", CoverageLevel::Explicit, "capability-guarded"),
267 flag("--api-key", CoverageLevel::Explicit),
268 flag("--device-auth", CoverageLevel::Explicit),
269 flag("--with-api-key", CoverageLevel::Explicit),
270 ],
271 vec![],
272 ),
273 command(
274 &["login", "status"],
275 CoverageLevel::Explicit,
276 None,
277 vec![],
278 vec![],
279 ),
280 command(&["logout"], CoverageLevel::Explicit, None, vec![], vec![]),
281 command(
283 &["features", "list"],
284 CoverageLevel::Explicit,
285 None,
286 vec![],
287 vec![],
288 ),
289 command(
291 &["app-server", "generate-ts"],
292 CoverageLevel::Explicit,
293 None,
294 vec![
295 flag("--experimental", CoverageLevel::Explicit),
296 flag("--out", CoverageLevel::Explicit),
297 flag("--prettier", CoverageLevel::Explicit),
298 ],
299 vec![],
300 ),
301 command(
302 &["app-server", "generate-json-schema"],
303 CoverageLevel::Explicit,
304 None,
305 vec![
306 flag("--experimental", CoverageLevel::Explicit),
307 flag("--out", CoverageLevel::Explicit),
308 ],
309 vec![],
310 ),
311 command(
313 &["responses-api-proxy"],
314 CoverageLevel::Explicit,
315 None,
316 vec![
317 flag("--port", CoverageLevel::Explicit),
318 flag("--server-info", CoverageLevel::Explicit),
319 flag("--http-shutdown", CoverageLevel::Explicit),
320 flag("--upstream-url", CoverageLevel::Explicit),
321 ],
322 vec![],
323 ),
324 command(
326 &["stdio-to-uds"],
327 CoverageLevel::Explicit,
328 None,
329 vec![],
330 vec![arg("SOCKET_PATH", CoverageLevel::Explicit)],
331 ),
332 command(&["sandbox"], CoverageLevel::Explicit, None, vec![], vec![]),
334 command(
335 &["sandbox", "macos"],
336 CoverageLevel::Explicit,
337 None,
338 vec![flag("--log-denials", CoverageLevel::Explicit)],
339 vec![arg("COMMAND", CoverageLevel::Explicit)],
340 ),
341 command(
342 &["sandbox", "linux"],
343 CoverageLevel::Explicit,
344 None,
345 vec![],
346 vec![arg("COMMAND", CoverageLevel::Explicit)],
347 ),
348 command(
349 &["sandbox", "windows"],
350 CoverageLevel::Explicit,
351 None,
352 vec![],
353 vec![arg("COMMAND", CoverageLevel::Explicit)],
354 ),
355 command(
357 &["execpolicy", "check"],
358 CoverageLevel::Explicit,
359 None,
360 vec![
361 flag("--policy", CoverageLevel::Explicit),
362 flag("--pretty", CoverageLevel::Explicit),
363 ],
364 vec![arg("COMMAND", CoverageLevel::Explicit)],
365 ),
366 command(
368 &["mcp-server"],
369 CoverageLevel::Explicit,
370 None,
371 vec![],
372 vec![],
373 ),
374 command(
375 &["app-server"],
376 CoverageLevel::Explicit,
377 None,
378 vec![flag("--analytics-default-enabled", CoverageLevel::Explicit)],
379 vec![],
380 ),
381 command(&["cloud"], CoverageLevel::Explicit, None, vec![], vec![]),
382 command(&["mcp"], CoverageLevel::Explicit, None, vec![], vec![]),
383 command(
384 &["mcp", "list"],
385 CoverageLevel::Explicit,
386 None,
387 vec![flag("--json", CoverageLevel::Explicit)],
388 vec![],
389 ),
390 command(
391 &["mcp", "get"],
392 CoverageLevel::Explicit,
393 None,
394 vec![flag("--json", CoverageLevel::Explicit)],
395 vec![arg("NAME", CoverageLevel::Explicit)],
396 ),
397 command(
398 &["mcp", "add"],
399 CoverageLevel::Explicit,
400 None,
401 vec![
402 flag("--url", CoverageLevel::Explicit),
403 flag("--bearer-token-env-var", CoverageLevel::Explicit),
404 flag("--env", CoverageLevel::Explicit),
405 ],
406 vec![
407 arg("NAME", CoverageLevel::Explicit),
408 arg("COMMAND", CoverageLevel::Explicit),
409 ],
410 ),
411 command(
412 &["mcp", "remove"],
413 CoverageLevel::Explicit,
414 None,
415 vec![],
416 vec![arg("NAME", CoverageLevel::Explicit)],
417 ),
418 command(
419 &["mcp", "logout"],
420 CoverageLevel::Explicit,
421 None,
422 vec![],
423 vec![arg("NAME", CoverageLevel::Explicit)],
424 ),
425 command(
426 &["mcp", "login"],
427 CoverageLevel::Explicit,
428 None,
429 vec![flag("--scopes", CoverageLevel::Explicit)],
430 vec![arg("NAME", CoverageLevel::Explicit)],
431 ),
432 command(
434 &["help"],
435 CoverageLevel::Explicit,
436 None,
437 vec![],
438 vec![arg("COMMAND", CoverageLevel::Explicit)],
439 ),
440 command(
441 &["exec", "help"],
442 CoverageLevel::Explicit,
443 None,
444 vec![],
445 vec![arg("COMMAND", CoverageLevel::Explicit)],
446 ),
447 command(
448 &["features", "help"],
449 CoverageLevel::Explicit,
450 None,
451 vec![],
452 vec![arg("COMMAND", CoverageLevel::Explicit)],
453 ),
454 command(
455 &["login", "help"],
456 CoverageLevel::Explicit,
457 None,
458 vec![],
459 vec![arg("COMMAND", CoverageLevel::Explicit)],
460 ),
461 command(
462 &["app-server", "help"],
463 CoverageLevel::Explicit,
464 None,
465 vec![],
466 vec![arg("COMMAND", CoverageLevel::Explicit)],
467 ),
468 command(
469 &["sandbox", "help"],
470 CoverageLevel::Explicit,
471 None,
472 vec![],
473 vec![arg("COMMAND", CoverageLevel::Explicit)],
474 ),
475 command(
476 &["cloud", "help"],
477 CoverageLevel::Explicit,
478 None,
479 vec![],
480 vec![arg("COMMAND", CoverageLevel::Explicit)],
481 ),
482 command(
483 &["mcp", "help"],
484 CoverageLevel::Explicit,
485 None,
486 vec![],
487 vec![arg("COMMAND", CoverageLevel::Explicit)],
488 ),
489 command(&["features"], CoverageLevel::Explicit, None, vec![], vec![]),
491 command(
493 &["features", "enable"],
494 CoverageLevel::Explicit,
495 None,
496 vec![],
497 vec![arg("FEATURE", CoverageLevel::Explicit)],
498 ),
499 command(
500 &["features", "disable"],
501 CoverageLevel::Explicit,
502 None,
503 vec![],
504 vec![arg("FEATURE", CoverageLevel::Explicit)],
505 ),
506 command(&["debug"], CoverageLevel::Explicit, None, vec![], vec![]),
507 command(
508 &["debug", "help"],
509 CoverageLevel::Explicit,
510 None,
511 vec![],
512 vec![arg("COMMAND", CoverageLevel::Explicit)],
513 ),
514 command(
515 &["debug", "app-server"],
516 CoverageLevel::Explicit,
517 None,
518 vec![],
519 vec![],
520 ),
521 command(
522 &["debug", "app-server", "help"],
523 CoverageLevel::Explicit,
524 None,
525 vec![],
526 vec![arg("COMMAND", CoverageLevel::Explicit)],
527 ),
528 command(
529 &["debug", "app-server", "send-message-v2"],
530 CoverageLevel::Explicit,
531 None,
532 vec![],
533 vec![arg("USER_MESSAGE", CoverageLevel::Explicit)],
534 ),
535 command(
536 &["exec", "review"],
537 CoverageLevel::Explicit,
538 None,
539 vec![
540 flag("--base", CoverageLevel::Explicit),
541 flag("--commit", CoverageLevel::Explicit),
542 flag("--json", CoverageLevel::Explicit),
543 flag("--skip-git-repo-check", CoverageLevel::Explicit),
544 flag("--title", CoverageLevel::Explicit),
545 flag("--uncommitted", CoverageLevel::Explicit),
546 ],
547 vec![arg("PROMPT", CoverageLevel::Explicit)],
548 ),
549 command(
550 &["review"],
551 CoverageLevel::Explicit,
552 None,
553 vec![
554 flag("--base", CoverageLevel::Explicit),
555 flag("--commit", CoverageLevel::Explicit),
556 flag("--title", CoverageLevel::Explicit),
557 flag("--uncommitted", CoverageLevel::Explicit),
558 ],
559 vec![arg("PROMPT", CoverageLevel::Explicit)],
560 ),
561 command(
562 &["resume"],
563 CoverageLevel::Explicit,
564 None,
565 vec![
566 flag("--all", CoverageLevel::Explicit),
567 flag("--last", CoverageLevel::Explicit),
568 ],
569 vec![
570 arg("PROMPT", CoverageLevel::Explicit),
571 arg("SESSION_ID", CoverageLevel::Explicit),
572 ],
573 ),
574 command(
575 &["fork"],
576 CoverageLevel::Explicit,
577 None,
578 vec![
579 flag("--all", CoverageLevel::Explicit),
580 flag("--last", CoverageLevel::Explicit),
581 ],
582 vec![
583 arg("PROMPT", CoverageLevel::Explicit),
584 arg("SESSION_ID", CoverageLevel::Explicit),
585 ],
586 ),
587 WrapperCommandCoverageV1 {
588 path: vec!["completion".to_string()],
589 level: CoverageLevel::IntentionallyUnsupported,
590 note: Some(
591 "Shell completion generation is out of scope for the wrapper.".to_string(),
592 ),
593 scope: None,
594 flags: None,
595 args: Some(vec![arg_note(
596 "SHELL",
597 CoverageLevel::IntentionallyUnsupported,
598 "Shell completion generation is out of scope for the wrapper.",
599 )]),
600 },
601 ],
602 }
603}