Skip to main content

sift_queue/cli/commands/
prime.rs

1use anyhow::Result;
2
3/// Execute the `sq prime` command.
4pub fn execute() -> Result<i32> {
5    println!("{}", generate());
6    Ok(0)
7}
8
9/// Generate the prime context string.
10pub fn generate() -> String {
11    let mut parts = Vec::new();
12
13    parts.push(
14        r#"# sq — Queue CLI and Queue-Native Task/Review Substrate
15
16`sq` manages work in a JSONL queue.
17
18Use it to:
19
20- add and organize review/task items
21- collect work from search results
22- inspect queue state
23- drive human or agent workflows from the queue
24
25## Core Workflow
26
271. Create items with `sq add` or `sq collect --by-file`
282. Inspect queue state with `sq list` and `sq show`
293. Update progress with `sq edit`, `sq close`, or `sq rm`
304. Use the queue directly, or hand it off to another consumer such as `sift`
31
32## `sq` Commands"#
33            .to_string(),
34    );
35
36    parts.push(generate_command_reference());
37
38    parts.join("\n\n")
39}
40
41fn generate_command_reference() -> String {
42    let cmd = crate::build_cli();
43    let mut lines = Vec::new();
44
45    for sub in cmd.get_subcommands() {
46        let name = sub.get_name();
47        if name == "prime" || name == "help" {
48            continue;
49        }
50
51        let about = sub.get_about().map(|a| a.to_string()).unwrap_or_default();
52        lines.push(format!("### `sq {}` — {}\n", name, about));
53        lines.push("```".to_string());
54
55        for arg in sub.get_arguments() {
56            if arg.is_hide_set() {
57                continue;
58            }
59            let id = arg.get_id().as_str();
60            if id == "help" || id == "version" {
61                continue;
62            }
63
64            // Skip positional arguments in the flags listing
65            let is_positional = arg.get_long().is_none() && arg.get_short().is_none();
66            if is_positional {
67                continue;
68            }
69
70            let long = arg.get_long().map(|l| format!("--{}", l));
71            let short = arg.get_short().map(|s| format!("-{}", s));
72            let names: Vec<String> = [short, long].into_iter().flatten().collect();
73            let names_str = names.join(", ");
74
75            // For boolean flags (num_vals == 0), don't show value name
76            let is_bool = arg.get_action().takes_values();
77            let value = if is_bool {
78                arg.get_value_names()
79                    .map(|v| {
80                        v.iter()
81                            .map(|s| s.to_string())
82                            .collect::<Vec<_>>()
83                            .join(" ")
84                    })
85                    .unwrap_or_default()
86            } else {
87                String::new()
88            };
89
90            let usage = if value.is_empty() {
91                names_str
92            } else {
93                format!("{} {}", names_str, value)
94            };
95
96            let help = arg.get_help().map(|h| h.to_string()).unwrap_or_default();
97
98            lines.push(format!("  {}  {}", usage, help));
99        }
100
101        lines.push("```".to_string());
102        lines.push(String::new());
103        lines.push(format!("For more information, use `sq {} --help`.", name));
104        lines.push(String::new());
105    }
106
107    lines.join("\n")
108}