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#"# Sift — Queue-Driven Review System
15
16Sift is a queue-driven review system where **humans make decisions** and **agents do the work**.
17
18## Core Workflow
19
201. Items enter the queue via `sq add` (with sources: text, diff, file, directory)
212. A human launches `sift` to review pending items in the TUI
223. For each item, the human can view the sources and spawn agents to act on them
234. When an agent finishes, its transcript is appended as a source on the item
24
25## `sq` Commands"#
26            .to_string(),
27    );
28
29    parts.push(generate_command_reference());
30
31    parts.join("\n\n")
32}
33
34fn generate_command_reference() -> String {
35    let cmd = crate::build_cli();
36    let mut lines = Vec::new();
37
38    for sub in cmd.get_subcommands() {
39        let name = sub.get_name();
40        if name == "prime" || name == "help" {
41            continue;
42        }
43
44        let about = sub.get_about().map(|a| a.to_string()).unwrap_or_default();
45        lines.push(format!("### `sq {}` — {}\n", name, about));
46        lines.push("```".to_string());
47
48        for arg in sub.get_arguments() {
49            if arg.is_hide_set() {
50                continue;
51            }
52            let id = arg.get_id().as_str();
53            if id == "help" || id == "version" {
54                continue;
55            }
56
57            // Skip positional arguments in the flags listing
58            let is_positional = arg.get_long().is_none() && arg.get_short().is_none();
59            if is_positional {
60                continue;
61            }
62
63            let long = arg.get_long().map(|l| format!("--{}", l));
64            let short = arg.get_short().map(|s| format!("-{}", s));
65            let names: Vec<String> = [short, long].into_iter().flatten().collect();
66            let names_str = names.join(", ");
67
68            // For boolean flags (num_vals == 0), don't show value name
69            let is_bool = arg.get_action().takes_values();
70            let value = if is_bool {
71                arg.get_value_names()
72                    .map(|v| {
73                        v.iter()
74                            .map(|s| s.to_string())
75                            .collect::<Vec<_>>()
76                            .join(" ")
77                    })
78                    .unwrap_or_default()
79            } else {
80                String::new()
81            };
82
83            let usage = if value.is_empty() {
84                names_str
85            } else {
86                format!("{} {}", names_str, value)
87            };
88
89            let help = arg.get_help().map(|h| h.to_string()).unwrap_or_default();
90
91            lines.push(format!("  {}  {}", usage, help));
92        }
93
94        lines.push("```".to_string());
95        lines.push(String::new());
96        lines.push(format!("For more information, use `sq {} --help`.", name));
97        lines.push(String::new());
98    }
99
100    lines.join("\n")
101}