Skip to main content

ytcli/cli/
cheatsheet.rs

1//! One-shot compact reference.
2//!
3//! The skill that ships with this tool stays deliberately small; an agent that
4//! wants the whole surface at once runs this instead of loading a large document
5//! it mostly will not use (`docs/adr/0006-agent-surface.md`).
6
7use std::io::Write;
8
9use clap::Args;
10
11use crate::exit::ExitCode;
12
13#[derive(Debug, Args)]
14pub struct CheatsheetArgs {
15    /// Narrow the sheet to one topic: issue, auth, queue, project, goal, attachment, format.
16    pub topic: Option<String>,
17}
18
19const SHEET: &str = include_str!("../../docs/cheatsheet.txt");
20
21#[must_use]
22pub fn run(args: &CheatsheetArgs) -> ExitCode {
23    let mut out = anstream::stdout();
24
25    // The sheet is compiled in from a text file, and a Windows checkout may have
26    // rewritten its line endings. Normalising here keeps the section splitting
27    // below platform-independent regardless of how the source was checked out.
28    let sheet = SHEET.replace("\r\n", "\n");
29
30    let Some(topic) = args.topic.as_deref() else {
31        let _ = write!(out, "{sheet}");
32        return ExitCode::Success;
33    };
34
35    // Sections are separated by a blank line and start with `## <topic>`.
36    let wanted = format!("## {topic}");
37    let mut found = false;
38    for block in sheet.split("\n\n") {
39        if block.starts_with(&wanted) {
40            let _ = writeln!(out, "{}", block.trim_end());
41            found = true;
42        }
43    }
44
45    if found {
46        ExitCode::Success
47    } else {
48        let mut err = anstream::stderr();
49        let _ = writeln!(
50            err,
51            "unknown topic `{topic}`; run `ytcli cheatsheet` for all"
52        );
53        ExitCode::Failure
54    }
55}