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-api-key", CoverageLevel::Explicit),
279 ],
280 vec![],
281 ),
282 command(
283 &["login", "status"],
284 CoverageLevel::Explicit,
285 None,
286 vec![],
287 vec![],
288 ),
289 command(&["logout"], CoverageLevel::Explicit, None, vec![], vec![]),
290 command(
292 &["features", "list"],
293 CoverageLevel::Explicit,
294 None,
295 vec![],
296 vec![],
297 ),
298 command(
300 &["app-server", "generate-ts"],
301 CoverageLevel::Explicit,
302 None,
303 vec![
304 flag("--experimental", CoverageLevel::Explicit),
305 flag("--out", CoverageLevel::Explicit),
306 flag("--prettier", CoverageLevel::Explicit),
307 ],
308 vec![],
309 ),
310 command(
311 &["app-server", "generate-json-schema"],
312 CoverageLevel::Explicit,
313 None,
314 vec![
315 flag("--experimental", CoverageLevel::Explicit),
316 flag("--out", CoverageLevel::Explicit),
317 ],
318 vec![],
319 ),
320 command(
322 &["responses-api-proxy"],
323 CoverageLevel::Explicit,
324 None,
325 vec![
326 flag("--port", CoverageLevel::Explicit),
327 flag("--server-info", CoverageLevel::Explicit),
328 flag("--http-shutdown", CoverageLevel::Explicit),
329 flag("--upstream-url", CoverageLevel::Explicit),
330 ],
331 vec![],
332 ),
333 command(
335 &["stdio-to-uds"],
336 CoverageLevel::Explicit,
337 None,
338 vec![],
339 vec![arg("SOCKET_PATH", CoverageLevel::Explicit)],
340 ),
341 command(&["sandbox"], CoverageLevel::Explicit, None, vec![], vec![]),
343 command(
344 &["sandbox", "macos"],
345 CoverageLevel::Explicit,
346 None,
347 vec![
348 flag("--allow-unix-socket", CoverageLevel::Explicit),
349 flag("--log-denials", CoverageLevel::Explicit),
350 ],
351 vec![arg("COMMAND", CoverageLevel::Explicit)],
352 ),
353 command(
354 &["sandbox", "linux"],
355 CoverageLevel::Explicit,
356 None,
357 vec![],
358 vec![arg("COMMAND", CoverageLevel::Explicit)],
359 ),
360 command(
361 &["sandbox", "windows"],
362 CoverageLevel::Explicit,
363 None,
364 vec![],
365 vec![arg("COMMAND", CoverageLevel::Explicit)],
366 ),
367 command(
369 &["execpolicy", "check"],
370 CoverageLevel::Explicit,
371 None,
372 vec![
373 flag("--policy", CoverageLevel::Explicit),
374 flag("--pretty", CoverageLevel::Explicit),
375 ],
376 vec![arg("COMMAND", CoverageLevel::Explicit)],
377 ),
378 command(
380 &["mcp-server"],
381 CoverageLevel::Explicit,
382 None,
383 vec![],
384 vec![],
385 ),
386 command(
387 &["app-server"],
388 CoverageLevel::Explicit,
389 None,
390 vec![
391 flag("--analytics-default-enabled", CoverageLevel::Explicit),
392 flag("--listen", CoverageLevel::Explicit),
393 flag("--ws-audience", CoverageLevel::Explicit),
394 flag("--ws-auth", CoverageLevel::Explicit),
395 flag("--ws-issuer", CoverageLevel::Explicit),
396 flag("--ws-max-clock-skew-seconds", CoverageLevel::Explicit),
397 flag("--ws-shared-secret-file", CoverageLevel::Explicit),
398 flag("--ws-token-file", CoverageLevel::Explicit),
399 flag("--ws-token-sha256", CoverageLevel::Explicit),
400 ],
401 vec![],
402 ),
403 command(
404 &["app-server", "proxy"],
405 CoverageLevel::Explicit,
406 None,
407 vec![flag("--sock", CoverageLevel::Explicit)],
408 vec![],
409 ),
410 command(&["cloud"], CoverageLevel::Explicit, None, vec![], vec![]),
411 command(
412 &["exec-server"],
413 CoverageLevel::Explicit,
414 None,
415 vec![flag("--listen", CoverageLevel::Explicit)],
416 vec![],
417 ),
418 command(&["mcp"], CoverageLevel::Explicit, None, vec![], vec![]),
419 command(
420 &["mcp", "list"],
421 CoverageLevel::Explicit,
422 None,
423 vec![flag("--json", CoverageLevel::Explicit)],
424 vec![],
425 ),
426 command(
427 &["mcp", "get"],
428 CoverageLevel::Explicit,
429 None,
430 vec![flag("--json", CoverageLevel::Explicit)],
431 vec![arg("NAME", CoverageLevel::Explicit)],
432 ),
433 command(
434 &["mcp", "add"],
435 CoverageLevel::Explicit,
436 None,
437 vec![
438 flag("--url", CoverageLevel::Explicit),
439 flag("--bearer-token-env-var", CoverageLevel::Explicit),
440 flag("--env", CoverageLevel::Explicit),
441 ],
442 vec![
443 arg("NAME", CoverageLevel::Explicit),
444 arg("COMMAND", CoverageLevel::Explicit),
445 ],
446 ),
447 command(
448 &["mcp", "remove"],
449 CoverageLevel::Explicit,
450 None,
451 vec![],
452 vec![arg("NAME", CoverageLevel::Explicit)],
453 ),
454 command(
455 &["mcp", "logout"],
456 CoverageLevel::Explicit,
457 None,
458 vec![],
459 vec![arg("NAME", CoverageLevel::Explicit)],
460 ),
461 command(
462 &["mcp", "login"],
463 CoverageLevel::Explicit,
464 None,
465 vec![flag("--scopes", CoverageLevel::Explicit)],
466 vec![arg("NAME", CoverageLevel::Explicit)],
467 ),
468 command(
470 &["help"],
471 CoverageLevel::Explicit,
472 None,
473 vec![],
474 vec![arg("COMMAND", CoverageLevel::Explicit)],
475 ),
476 command(
477 &["exec", "help"],
478 CoverageLevel::Explicit,
479 None,
480 vec![],
481 vec![arg("COMMAND", CoverageLevel::Explicit)],
482 ),
483 command(
484 &["features", "help"],
485 CoverageLevel::Explicit,
486 None,
487 vec![],
488 vec![arg("COMMAND", CoverageLevel::Explicit)],
489 ),
490 command(
491 &["login", "help"],
492 CoverageLevel::Explicit,
493 None,
494 vec![],
495 vec![arg("COMMAND", CoverageLevel::Explicit)],
496 ),
497 command(
498 &["app-server", "help"],
499 CoverageLevel::Explicit,
500 None,
501 vec![],
502 vec![arg("COMMAND", CoverageLevel::Explicit)],
503 ),
504 command(
505 &["sandbox", "help"],
506 CoverageLevel::Explicit,
507 None,
508 vec![],
509 vec![arg("COMMAND", CoverageLevel::Explicit)],
510 ),
511 command(
512 &["cloud", "help"],
513 CoverageLevel::Explicit,
514 None,
515 vec![],
516 vec![arg("COMMAND", CoverageLevel::Explicit)],
517 ),
518 command(
519 &["mcp", "help"],
520 CoverageLevel::Explicit,
521 None,
522 vec![],
523 vec![arg("COMMAND", CoverageLevel::Explicit)],
524 ),
525 command(&["features"], CoverageLevel::Explicit, None, vec![], vec![]),
527 command(
529 &["features", "enable"],
530 CoverageLevel::Explicit,
531 None,
532 vec![],
533 vec![arg("FEATURE", CoverageLevel::Explicit)],
534 ),
535 command(
536 &["features", "disable"],
537 CoverageLevel::Explicit,
538 None,
539 vec![],
540 vec![arg("FEATURE", CoverageLevel::Explicit)],
541 ),
542 command(&["debug"], CoverageLevel::Explicit, None, vec![], vec![]),
543 command(
544 &["debug", "help"],
545 CoverageLevel::Explicit,
546 None,
547 vec![],
548 vec![arg("COMMAND", CoverageLevel::Explicit)],
549 ),
550 command(
551 &["debug", "app-server"],
552 CoverageLevel::Explicit,
553 None,
554 vec![],
555 vec![],
556 ),
557 command(
558 &["debug", "app-server", "help"],
559 CoverageLevel::Explicit,
560 None,
561 vec![],
562 vec![arg("COMMAND", CoverageLevel::Explicit)],
563 ),
564 command(
565 &["debug", "app-server", "send-message-v2"],
566 CoverageLevel::Explicit,
567 None,
568 vec![],
569 vec![arg("USER_MESSAGE", CoverageLevel::Explicit)],
570 ),
571 command(
572 &["debug", "models"],
573 CoverageLevel::Explicit,
574 None,
575 vec![flag("--bundled", CoverageLevel::Explicit)],
576 vec![],
577 ),
578 command(
579 &["debug", "prompt-input"],
580 CoverageLevel::Explicit,
581 None,
582 vec![flag("--image", CoverageLevel::Explicit)],
583 vec![arg("PROMPT", CoverageLevel::Explicit)],
584 ),
585 command(
586 &["exec", "review"],
587 CoverageLevel::Explicit,
588 None,
589 vec![
590 flag("--base", CoverageLevel::Explicit),
591 flag("--commit", CoverageLevel::Explicit),
592 flag("--ephemeral", CoverageLevel::Explicit),
593 flag("--ignore-rules", CoverageLevel::Explicit),
594 flag("--ignore-user-config", CoverageLevel::Explicit),
595 flag("--json", CoverageLevel::Explicit),
596 flag("--output-last-message", CoverageLevel::Explicit),
597 flag("--skip-git-repo-check", CoverageLevel::Explicit),
598 flag("--title", CoverageLevel::Explicit),
599 flag("--uncommitted", CoverageLevel::Explicit),
600 ],
601 vec![arg("PROMPT", CoverageLevel::Explicit)],
602 ),
603 command(
604 &["review"],
605 CoverageLevel::Explicit,
606 None,
607 vec![
608 flag("--base", CoverageLevel::Explicit),
609 flag("--commit", CoverageLevel::Explicit),
610 flag("--title", CoverageLevel::Explicit),
611 flag("--uncommitted", CoverageLevel::Explicit),
612 ],
613 vec![arg("PROMPT", CoverageLevel::Explicit)],
614 ),
615 command(
616 &["resume"],
617 CoverageLevel::Explicit,
618 None,
619 vec![
620 flag("--all", CoverageLevel::Explicit),
621 flag("--include-non-interactive", CoverageLevel::Explicit),
622 flag("--last", CoverageLevel::Explicit),
623 ],
624 vec![
625 arg("PROMPT", CoverageLevel::Explicit),
626 arg("SESSION_ID", CoverageLevel::Explicit),
627 ],
628 ),
629 command(
630 &["fork"],
631 CoverageLevel::Explicit,
632 None,
633 vec![
634 flag("--all", CoverageLevel::Explicit),
635 flag("--last", CoverageLevel::Explicit),
636 ],
637 vec![
638 arg("PROMPT", CoverageLevel::Explicit),
639 arg("SESSION_ID", CoverageLevel::Explicit),
640 ],
641 ),
642 command(&["plugin"], CoverageLevel::Explicit, None, vec![], vec![]),
643 command(
644 &["plugin", "help"],
645 CoverageLevel::Explicit,
646 None,
647 vec![],
648 vec![arg("COMMAND", CoverageLevel::Explicit)],
649 ),
650 command(
651 &["plugin", "marketplace"],
652 CoverageLevel::Explicit,
653 None,
654 vec![],
655 vec![],
656 ),
657 command(
658 &["plugin", "marketplace", "add"],
659 CoverageLevel::Explicit,
660 None,
661 vec![
662 flag("--ref", CoverageLevel::Explicit),
663 flag("--sparse", CoverageLevel::Explicit),
664 ],
665 vec![arg("SOURCE", CoverageLevel::Explicit)],
666 ),
667 command(
668 &["plugin", "marketplace", "help"],
669 CoverageLevel::Explicit,
670 None,
671 vec![],
672 vec![arg("COMMAND", CoverageLevel::Explicit)],
673 ),
674 command(
675 &["plugin", "marketplace", "remove"],
676 CoverageLevel::Explicit,
677 None,
678 vec![],
679 vec![arg("MARKETPLACE_NAME", CoverageLevel::Explicit)],
680 ),
681 command(
682 &["plugin", "marketplace", "upgrade"],
683 CoverageLevel::Explicit,
684 None,
685 vec![],
686 vec![arg("MARKETPLACE_NAME", CoverageLevel::Explicit)],
687 ),
688 WrapperCommandCoverageV1 {
689 path: vec!["completion".to_string()],
690 level: CoverageLevel::IntentionallyUnsupported,
691 note: Some(
692 "Shell completion generation is out of scope for the wrapper.".to_string(),
693 ),
694 scope: None,
695 flags: None,
696 args: Some(vec![arg_note(
697 "SHELL",
698 CoverageLevel::IntentionallyUnsupported,
699 "Shell completion generation is out of scope for the wrapper.",
700 )]),
701 },
702 ],
703 }
704}