1use crate::envelope::Envelope;
5use crate::error::EXIT_CODES;
6use serde_json::json;
7
8pub fn text() -> String {
10 let mut s = String::new();
11 s.push_str("fez agent guide\n\n");
12 s.push_str("Discovery loop:\n");
13 s.push_str(" 1. fez capabilities list capability ids\n");
14 s.push_str(" 2. fez describe <id> --json inputs, flags, output kind, examples\n");
15 s.push_str(" 3. fez <command> ... --json invoke; parse the fez/v1 envelope\n\n");
16 s.push_str("Envelope (fez/v1): every --json response is\n");
17 s.push_str(
18 " {apiVersion:\"fez/v1\", kind, host, status:\"ok\"|\"error\", data?, error?, hints?}\n\n",
19 );
20 s.push_str("Global flags: --host <h> --json --dry-run --force\n\n");
21 s.push_str("Exit codes:\n");
22 for e in EXIT_CODES {
23 s.push_str(&format!(" {:>2} {:<14} {}\n", e.code, e.label, e.meaning));
24 }
25 s.push_str(
26 "\nEnv vars: FEZ_BRIDGE, FEZ_AUDIT, FEZ_SSH_CONFIG, FEZ_ACTOR, FEZ_CORRELATION_ID.\n",
27 );
28 s
29}
30
31pub fn data() -> serde_json::Value {
33 json!({
34 "discovery": [
35 "fez capabilities",
36 "fez describe <id> --json",
37 "fez <command> ... --json"
38 ],
39 "envelope": {
40 "apiVersion": "fez/v1",
41 "fields": ["kind", "host", "status", "data", "error", "hints"]
42 },
43 "globalFlags": ["--host", "--json", "--dry-run", "--force"],
44 "exitCodes": EXIT_CODES.iter().map(|e| json!({
45 "code": e.code, "label": e.label, "meaning": e.meaning
46 })).collect::<Vec<_>>(),
47 "envVars": [
48 "FEZ_BRIDGE",
49 "FEZ_AUDIT",
50 "FEZ_SSH_CONFIG",
51 "FEZ_ACTOR",
52 "FEZ_CORRELATION_ID"
53 ]
54 })
55}
56
57pub fn run(host: &str, as_json: bool) -> i32 {
59 if as_json {
60 println!(
61 "{}",
62 Envelope::ok("AgentGuide", host, data()).to_json_string()
63 );
64 } else {
65 print!("{}", text());
66 }
67 0
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn text_lists_every_exit_code() {
76 let t = text();
77 for e in EXIT_CODES {
78 assert!(t.contains(e.label), "guide text missing {}", e.label);
79 }
80 }
81
82 #[test]
83 fn data_has_exit_codes_and_envelope() {
84 let d = data();
85 assert!(d["exitCodes"].as_array().unwrap().len() == EXIT_CODES.len());
86 assert_eq!(d["envelope"]["apiVersion"], "fez/v1");
87 }
88}