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("--remote", CoverageLevel::Explicit),
161 flag("--remote-auth-token-env", CoverageLevel::Explicit),
162 flag("--ask-for-approval", CoverageLevel::Explicit),
163 flag("--sandbox", CoverageLevel::Explicit),
164 flag("--full-auto", CoverageLevel::Explicit),
165 flag(
166 "--dangerously-bypass-approvals-and-sandbox",
167 CoverageLevel::Explicit,
168 ),
169 flag("--local-provider", CoverageLevel::Explicit),
170 flag("--oss", CoverageLevel::Explicit),
171 flag("--search", CoverageLevel::Explicit),
172 ],
173 vec![],
174 ),
175 command(
177 &["exec"],
178 CoverageLevel::Explicit,
179 None,
180 vec![
181 flag("--color", CoverageLevel::Explicit),
182 flag("--ephemeral", CoverageLevel::Explicit),
183 flag("--ignore-rules", CoverageLevel::Explicit),
184 flag("--ignore-user-config", CoverageLevel::Explicit),
185 flag("--skip-git-repo-check", CoverageLevel::Explicit),
186 flag("--json", CoverageLevel::Explicit),
187 flag("--output-last-message", CoverageLevel::Explicit),
188 flag_note(
189 "--output-schema",
190 CoverageLevel::Explicit,
191 "capability-guarded",
192 ),
193 ],
194 vec![arg("PROMPT", CoverageLevel::Explicit)],
195 ),
196 command(
198 &["exec", "resume"],
199 CoverageLevel::Explicit,
200 None,
201 vec![
202 flag("--ephemeral", CoverageLevel::Explicit),
203 flag("--ignore-rules", CoverageLevel::Explicit),
204 flag("--ignore-user-config", CoverageLevel::Explicit),
205 flag("--json", CoverageLevel::Explicit),
206 flag("--output-last-message", CoverageLevel::Explicit),
207 flag("--skip-git-repo-check", CoverageLevel::Explicit),
208 flag("--last", CoverageLevel::Explicit),
209 flag("--all", CoverageLevel::Explicit),
210 ],
211 vec![
212 arg("PROMPT", CoverageLevel::Explicit),
213 arg("SESSION_ID", CoverageLevel::Explicit),
214 ],
215 ),
216 command(
218 &["apply"],
219 CoverageLevel::Explicit,
220 None,
221 vec![],
222 vec![arg("TASK_ID", CoverageLevel::Explicit)],
223 ),
224 command(
226 &["cloud", "diff"],
227 CoverageLevel::Explicit,
228 None,
229 vec![flag("--attempt", CoverageLevel::Explicit)],
230 vec![arg("TASK_ID", CoverageLevel::Explicit)],
231 ),
232 command(
233 &["cloud", "apply"],
234 CoverageLevel::Explicit,
235 None,
236 vec![flag("--attempt", CoverageLevel::Explicit)],
237 vec![arg("TASK_ID", CoverageLevel::Explicit)],
238 ),
239 command(
240 &["cloud", "status"],
241 CoverageLevel::Explicit,
242 None,
243 vec![],
244 vec![arg("TASK_ID", CoverageLevel::Explicit)],
245 ),
246 command(
247 &["cloud", "list"],
248 CoverageLevel::Explicit,
249 None,
250 vec![
251 flag("--cursor", CoverageLevel::Explicit),
252 flag("--env", CoverageLevel::Explicit),
253 flag("--json", CoverageLevel::Explicit),
254 flag("--limit", CoverageLevel::Explicit),
255 ],
256 vec![],
257 ),
258 command(
259 &["cloud", "exec"],
260 CoverageLevel::Explicit,
261 None,
262 vec![
263 flag("--env", CoverageLevel::Explicit),
264 flag("--attempts", CoverageLevel::Explicit),
265 flag("--branch", CoverageLevel::Explicit),
266 ],
267 vec![arg("QUERY", CoverageLevel::Explicit)],
268 ),
269 command(
271 &["login"],
272 CoverageLevel::Explicit,
273 None,
274 vec![
275 flag_note("--mcp", CoverageLevel::Explicit, "capability-guarded"),
276 flag("--api-key", CoverageLevel::Explicit),
277 flag("--device-auth", CoverageLevel::Explicit),
278 flag("--with-access-token", CoverageLevel::Explicit),
279 flag("--with-api-key", CoverageLevel::Explicit),
280 ],
281 vec![],
282 ),
283 command(
284 &["login", "status"],
285 CoverageLevel::Explicit,
286 None,
287 vec![],
288 vec![],
289 ),
290 command(&["logout"], CoverageLevel::Explicit, None, vec![], vec![]),
291 command(
293 &["features", "list"],
294 CoverageLevel::Explicit,
295 None,
296 vec![],
297 vec![],
298 ),
299 command(
301 &["app-server", "generate-ts"],
302 CoverageLevel::Explicit,
303 None,
304 vec![
305 flag("--experimental", CoverageLevel::Explicit),
306 flag("--out", CoverageLevel::Explicit),
307 flag("--prettier", CoverageLevel::Explicit),
308 ],
309 vec![],
310 ),
311 command(
312 &["app-server", "generate-json-schema"],
313 CoverageLevel::Explicit,
314 None,
315 vec![
316 flag("--experimental", CoverageLevel::Explicit),
317 flag("--out", CoverageLevel::Explicit),
318 ],
319 vec![],
320 ),
321 command(
323 &["responses-api-proxy"],
324 CoverageLevel::Explicit,
325 None,
326 vec![
327 flag("--port", CoverageLevel::Explicit),
328 flag("--server-info", CoverageLevel::Explicit),
329 flag("--http-shutdown", CoverageLevel::Explicit),
330 flag("--upstream-url", CoverageLevel::Explicit),
331 ],
332 vec![],
333 ),
334 command(
336 &["stdio-to-uds"],
337 CoverageLevel::Explicit,
338 None,
339 vec![],
340 vec![arg("SOCKET_PATH", CoverageLevel::Explicit)],
341 ),
342 command(&["sandbox"], CoverageLevel::Explicit, None, vec![], vec![]),
344 command(
345 &["sandbox", "macos"],
346 CoverageLevel::Explicit,
347 None,
348 vec![
349 flag("--allow-unix-socket", CoverageLevel::Explicit),
350 flag("--include-managed-config", CoverageLevel::Explicit),
351 flag("--log-denials", CoverageLevel::Explicit),
352 flag("--permissions-profile", CoverageLevel::Explicit),
353 ],
354 vec![arg("COMMAND", CoverageLevel::Explicit)],
355 ),
356 command(
357 &["sandbox", "linux"],
358 CoverageLevel::Explicit,
359 None,
360 vec![
361 flag("--include-managed-config", CoverageLevel::Explicit),
362 flag("--permissions-profile", CoverageLevel::Explicit),
363 ],
364 vec![arg("COMMAND", CoverageLevel::Explicit)],
365 ),
366 command(
367 &["sandbox", "windows"],
368 CoverageLevel::Explicit,
369 None,
370 vec![
371 flag("--include-managed-config", CoverageLevel::Explicit),
372 flag("--permissions-profile", CoverageLevel::Explicit),
373 ],
374 vec![arg("COMMAND", CoverageLevel::Explicit)],
375 ),
376 command(
378 &["execpolicy", "check"],
379 CoverageLevel::Explicit,
380 None,
381 vec![
382 flag("--policy", CoverageLevel::Explicit),
383 flag("--pretty", CoverageLevel::Explicit),
384 ],
385 vec![arg("COMMAND", CoverageLevel::Explicit)],
386 ),
387 command(
389 &["mcp-server"],
390 CoverageLevel::Explicit,
391 None,
392 vec![],
393 vec![],
394 ),
395 command(
396 &["app-server"],
397 CoverageLevel::Explicit,
398 None,
399 vec![
400 flag("--analytics-default-enabled", CoverageLevel::Explicit),
401 flag("--listen", CoverageLevel::Explicit),
402 flag("--ws-audience", CoverageLevel::Explicit),
403 flag("--ws-auth", CoverageLevel::Explicit),
404 flag("--ws-issuer", CoverageLevel::Explicit),
405 flag("--ws-max-clock-skew-seconds", CoverageLevel::Explicit),
406 flag("--ws-shared-secret-file", CoverageLevel::Explicit),
407 flag("--ws-token-file", CoverageLevel::Explicit),
408 flag("--ws-token-sha256", CoverageLevel::Explicit),
409 ],
410 vec![],
411 ),
412 command(
413 &["app-server", "proxy"],
414 CoverageLevel::Explicit,
415 None,
416 vec![flag("--sock", CoverageLevel::Explicit)],
417 vec![],
418 ),
419 command(&["cloud"], CoverageLevel::Explicit, None, vec![], vec![]),
420 command(
421 &["exec-server"],
422 CoverageLevel::Explicit,
423 None,
424 vec![
425 flag("--executor-id", CoverageLevel::Explicit),
426 flag("--listen", CoverageLevel::Explicit),
427 flag("--name", CoverageLevel::Explicit),
428 ],
429 vec![],
430 ),
431 command(&["update"], CoverageLevel::Explicit, None, vec![], vec![]),
432 command(&["mcp"], CoverageLevel::Explicit, None, vec![], vec![]),
433 command(
434 &["mcp", "list"],
435 CoverageLevel::Explicit,
436 None,
437 vec![flag("--json", CoverageLevel::Explicit)],
438 vec![],
439 ),
440 command(
441 &["mcp", "get"],
442 CoverageLevel::Explicit,
443 None,
444 vec![flag("--json", CoverageLevel::Explicit)],
445 vec![arg("NAME", CoverageLevel::Explicit)],
446 ),
447 command(
448 &["mcp", "add"],
449 CoverageLevel::Explicit,
450 None,
451 vec![
452 flag("--url", CoverageLevel::Explicit),
453 flag("--bearer-token-env-var", CoverageLevel::Explicit),
454 flag("--env", CoverageLevel::Explicit),
455 ],
456 vec![
457 arg("NAME", CoverageLevel::Explicit),
458 arg("COMMAND", CoverageLevel::Explicit),
459 ],
460 ),
461 command(
462 &["mcp", "remove"],
463 CoverageLevel::Explicit,
464 None,
465 vec![],
466 vec![arg("NAME", CoverageLevel::Explicit)],
467 ),
468 command(
469 &["mcp", "logout"],
470 CoverageLevel::Explicit,
471 None,
472 vec![],
473 vec![arg("NAME", CoverageLevel::Explicit)],
474 ),
475 command(
476 &["mcp", "login"],
477 CoverageLevel::Explicit,
478 None,
479 vec![flag("--scopes", CoverageLevel::Explicit)],
480 vec![arg("NAME", CoverageLevel::Explicit)],
481 ),
482 command(
484 &["help"],
485 CoverageLevel::Explicit,
486 None,
487 vec![],
488 vec![arg("COMMAND", CoverageLevel::Explicit)],
489 ),
490 command(
491 &["exec", "help"],
492 CoverageLevel::Explicit,
493 None,
494 vec![],
495 vec![arg("COMMAND", CoverageLevel::Explicit)],
496 ),
497 command(
498 &["features", "help"],
499 CoverageLevel::Explicit,
500 None,
501 vec![],
502 vec![arg("COMMAND", CoverageLevel::Explicit)],
503 ),
504 command(
505 &["login", "help"],
506 CoverageLevel::Explicit,
507 None,
508 vec![],
509 vec![arg("COMMAND", CoverageLevel::Explicit)],
510 ),
511 command(
512 &["app-server", "help"],
513 CoverageLevel::Explicit,
514 None,
515 vec![],
516 vec![arg("COMMAND", CoverageLevel::Explicit)],
517 ),
518 command(
519 &["sandbox", "help"],
520 CoverageLevel::Explicit,
521 None,
522 vec![],
523 vec![arg("COMMAND", CoverageLevel::Explicit)],
524 ),
525 command(
526 &["cloud", "help"],
527 CoverageLevel::Explicit,
528 None,
529 vec![],
530 vec![arg("COMMAND", CoverageLevel::Explicit)],
531 ),
532 command(
533 &["mcp", "help"],
534 CoverageLevel::Explicit,
535 None,
536 vec![],
537 vec![arg("COMMAND", CoverageLevel::Explicit)],
538 ),
539 command(&["features"], CoverageLevel::Explicit, None, vec![], vec![]),
541 command(
543 &["features", "enable"],
544 CoverageLevel::Explicit,
545 None,
546 vec![],
547 vec![arg("FEATURE", CoverageLevel::Explicit)],
548 ),
549 command(
550 &["features", "disable"],
551 CoverageLevel::Explicit,
552 None,
553 vec![],
554 vec![arg("FEATURE", CoverageLevel::Explicit)],
555 ),
556 command(&["debug"], CoverageLevel::Explicit, None, vec![], vec![]),
557 command(
558 &["debug", "help"],
559 CoverageLevel::Explicit,
560 None,
561 vec![],
562 vec![arg("COMMAND", CoverageLevel::Explicit)],
563 ),
564 command(
565 &["debug", "app-server"],
566 CoverageLevel::Explicit,
567 None,
568 vec![],
569 vec![],
570 ),
571 command(
572 &["debug", "app-server", "help"],
573 CoverageLevel::Explicit,
574 None,
575 vec![],
576 vec![arg("COMMAND", CoverageLevel::Explicit)],
577 ),
578 command(
579 &["debug", "app-server", "send-message-v2"],
580 CoverageLevel::Explicit,
581 None,
582 vec![],
583 vec![arg("USER_MESSAGE", CoverageLevel::Explicit)],
584 ),
585 command(
586 &["debug", "models"],
587 CoverageLevel::Explicit,
588 None,
589 vec![flag("--bundled", CoverageLevel::Explicit)],
590 vec![],
591 ),
592 command(
593 &["debug", "prompt-input"],
594 CoverageLevel::Explicit,
595 None,
596 vec![flag("--image", CoverageLevel::Explicit)],
597 vec![arg("PROMPT", CoverageLevel::Explicit)],
598 ),
599 command(
600 &["exec", "review"],
601 CoverageLevel::Explicit,
602 None,
603 vec![
604 flag("--base", CoverageLevel::Explicit),
605 flag("--commit", CoverageLevel::Explicit),
606 flag("--ephemeral", CoverageLevel::Explicit),
607 flag("--ignore-rules", CoverageLevel::Explicit),
608 flag("--ignore-user-config", CoverageLevel::Explicit),
609 flag("--json", CoverageLevel::Explicit),
610 flag("--output-last-message", CoverageLevel::Explicit),
611 flag("--skip-git-repo-check", CoverageLevel::Explicit),
612 flag("--title", CoverageLevel::Explicit),
613 flag("--uncommitted", CoverageLevel::Explicit),
614 ],
615 vec![arg("PROMPT", CoverageLevel::Explicit)],
616 ),
617 command(
618 &["review"],
619 CoverageLevel::Explicit,
620 None,
621 vec![
622 flag("--base", CoverageLevel::Explicit),
623 flag("--commit", CoverageLevel::Explicit),
624 flag("--title", CoverageLevel::Explicit),
625 flag("--uncommitted", CoverageLevel::Explicit),
626 ],
627 vec![arg("PROMPT", CoverageLevel::Explicit)],
628 ),
629 command(
630 &["resume"],
631 CoverageLevel::Explicit,
632 None,
633 vec![
634 flag("--all", CoverageLevel::Explicit),
635 flag("--include-non-interactive", CoverageLevel::Explicit),
636 flag("--last", CoverageLevel::Explicit),
637 ],
638 vec![
639 arg("PROMPT", CoverageLevel::Explicit),
640 arg("SESSION_ID", CoverageLevel::Explicit),
641 ],
642 ),
643 command(
644 &["fork"],
645 CoverageLevel::Explicit,
646 None,
647 vec![
648 flag("--all", CoverageLevel::Explicit),
649 flag("--last", CoverageLevel::Explicit),
650 ],
651 vec![
652 arg("PROMPT", CoverageLevel::Explicit),
653 arg("SESSION_ID", CoverageLevel::Explicit),
654 ],
655 ),
656 command(&["plugin"], CoverageLevel::Explicit, None, vec![], vec![]),
657 command(
658 &["plugin", "help"],
659 CoverageLevel::Explicit,
660 None,
661 vec![],
662 vec![arg("COMMAND", CoverageLevel::Explicit)],
663 ),
664 command(
665 &["plugin", "marketplace"],
666 CoverageLevel::Explicit,
667 None,
668 vec![],
669 vec![],
670 ),
671 command(
672 &["plugin", "marketplace", "add"],
673 CoverageLevel::Explicit,
674 None,
675 vec![
676 flag("--ref", CoverageLevel::Explicit),
677 flag("--sparse", CoverageLevel::Explicit),
678 ],
679 vec![arg("SOURCE", CoverageLevel::Explicit)],
680 ),
681 command(
682 &["plugin", "marketplace", "help"],
683 CoverageLevel::Explicit,
684 None,
685 vec![],
686 vec![arg("COMMAND", CoverageLevel::Explicit)],
687 ),
688 command(
689 &["plugin", "marketplace", "remove"],
690 CoverageLevel::Explicit,
691 None,
692 vec![],
693 vec![arg("MARKETPLACE_NAME", CoverageLevel::Explicit)],
694 ),
695 command(
696 &["plugin", "marketplace", "upgrade"],
697 CoverageLevel::Explicit,
698 None,
699 vec![],
700 vec![arg("MARKETPLACE_NAME", CoverageLevel::Explicit)],
701 ),
702 WrapperCommandCoverageV1 {
703 path: vec!["completion".to_string()],
704 level: CoverageLevel::IntentionallyUnsupported,
705 note: Some(
706 "Shell completion generation is out of scope for the wrapper.".to_string(),
707 ),
708 scope: None,
709 flags: None,
710 args: Some(vec![arg_note(
711 "SHELL",
712 CoverageLevel::IntentionallyUnsupported,
713 "Shell completion generation is out of scope for the wrapper.",
714 )]),
715 },
716 ],
717 }
718}