1use crate::Installer;
2use crate::cli::flag_block;
3use crate::textfmt::{self, Columns};
4
5impl Installer {
6 #[must_use]
9 pub fn usage(&self) -> String {
10 self.usage_for(None)
11 }
12
13 #[must_use]
25 pub fn usage_hint(&self) -> String {
26 let n = self.skills().len();
27 let plural = if n == 1 { "skill" } else { "skills" };
28 format!(
29 "Run \"{tool} {cmd}\" to install the {n} agent {plural} embedded in {tool}.",
30 tool = self.tool_name(),
31 cmd = self.command_name(),
32 )
33 }
34
35 pub(crate) fn usage_for(&self, sub: Option<&str>) -> String {
41 let (summary, lines) = self.headings(sub);
42 let default_agents: Vec<String> =
43 self.default_agents().iter().map(ToString::to_string).collect();
44
45 let mut skills = Columns::default();
46 for sk in self.skills().skills() {
47 skills.push([format!(" {}", sk.name()), textfmt::first_line(sk.description())]);
48 }
49
50 let flags =
51 flag_block(&self.agent_choices(), &default_agents.join(","), self.default_scope());
52 let out = format!(
53 "{summary}\n\nUsage:\n{lines}\nFlags:\n{flags}\nEmbedded skills:\n{}",
54 skills.render()
55 );
56 textfmt::trim_lines(&out)
57 }
58
59 fn headings(&self, sub: Option<&str>) -> (String, String) {
61 let (tool, cmd) = (self.tool_name(), self.command_name());
62 let line =
63 |name: &str, pad: &str| format!(" {tool} {cmd} {name}{pad} [flags] [skill...]\n");
64 match sub {
65 Some("install") => (
69 format!(
70 "Install the agent skills embedded in {tool}, \
71 and remove the ones it no longer carries."
72 ),
73 line("install", ""),
74 ),
75 Some("uninstall") => {
76 (format!("Remove the agent skills embedded in {tool}."), line("uninstall", ""))
77 }
78 Some("list") => (
79 format!("Show the agent skills embedded in {tool}, and where each one stands."),
80 line("list", ""),
81 ),
82 _ => (
83 format!("Manage the agent skills embedded in {tool}."),
84 line("install", " ") + &line("uninstall", "") + &line("list", " "),
85 ),
86 }
87 }
88}