zad_cli/cli/
debug_agent.rs1use std::fmt::Write as _;
12
13pub fn render() -> String {
14 let mut out = String::new();
15 let version = zad::version();
16
17 let _ = writeln!(out, "zad {version} — diagnostics for agents");
18 out.push('\n');
19
20 out.push_str("Log files:\n");
21 match zad::logging::log_path() {
22 Some(p) => {
23 let _ = writeln!(out, " {}", p.display());
24 let _ = writeln!(
25 out,
26 " (rolled daily; the file log is always on, regardless of --debug)"
27 );
28 }
29 None => out.push_str(" <unable to resolve a log directory on this platform>\n"),
30 }
31 out.push('\n');
32
33 out.push_str("Config precedence (first match wins):\n");
34 out.push_str(" 1. Project-local ~/.zad/projects/<slug>/services/<svc>/\n");
35 out.push_str(" 2. Global service ~/.zad/services/<svc>/\n");
36 out.push_str(" 3. Built-in defaults\n");
37 out.push_str("Permissions intersect rather than replace: project-local can only tighten\n");
38 out.push_str("the global file, never loosen it.\n");
39 out.push('\n');
40
41 out.push_str("Resolved paths for the current working directory:\n");
42 match zad::config::path::zad_home() {
43 Ok(p) => {
44 let _ = writeln!(out, " ZAD_HOME {}", p.display());
45 }
46 Err(e) => {
47 let _ = writeln!(out, " ZAD_HOME <unresolved: {e}>");
48 }
49 }
50 match zad::config::path::project_slug() {
51 Ok(s) => {
52 let _ = writeln!(out, " project slug {s}");
53 }
54 Err(e) => {
55 let _ = writeln!(out, " project slug <unresolved: {e}>");
56 }
57 }
58 match zad::config::path::project_dir() {
59 Ok(p) => {
60 let _ = writeln!(out, " project dir {}", p.display());
61 }
62 Err(e) => {
63 let _ = writeln!(out, " project dir <unresolved: {e}>");
64 }
65 }
66 out.push('\n');
67
68 out.push_str("Environment variables:\n");
69 out.push_str(" ZAD_HOME_OVERRIDE Override $HOME when resolving ~/.zad (tests only).\n");
70 out.push_str(" ZAD_SECRETS_MEMORY `1` = in-memory keychain backend (tests only).\n");
71 out.push_str(
72 " RUST_LOG Standard tracing filter, e.g. `zad=debug`. Overrides --debug.\n",
73 );
74 out.push('\n');
75
76 out.push_str("Verbose output:\n");
77 out.push_str(
78 " --debug Emit debug-level logs to stderr in addition to the file log.\n",
79 );
80 out.push('\n');
81
82 out.push_str("Diagnostic commands:\n");
83 out.push_str(" zad --help-agent Compact prompt-injectable CLI summary.\n");
84 out.push_str(" zad commands Enumerate every command.\n");
85 out.push_str(" zad commands <name> Flags and exit codes for one command.\n");
86 out.push_str(" zad man [command] Reference manpages embedded at build time.\n");
87 out.push_str(" zad docs [topic] Topic docs embedded at build time.\n");
88 out.push_str(" zad service list Configured services for this project.\n");
89 out.push_str(
90 " zad <svc> permissions show Effective permissions for a service (global ∩ local).\n",
91 );
92 out.push_str(
93 " zad <svc> permissions path Where the TOML files that drive permissions live.\n",
94 );
95 out.push('\n');
96
97 out.push_str("Build metadata:\n");
98 let _ = writeln!(out, " version {version}");
99 let _ = writeln!(
100 out,
101 " target {}",
102 option_env!("TARGET").unwrap_or(std::env::consts::ARCH)
103 );
104 let _ = writeln!(out, " profile {}", profile());
105 out.push('\n');
106
107 out
108}
109
110const fn profile() -> &'static str {
111 if cfg!(debug_assertions) {
112 "debug"
113 } else {
114 "release"
115 }
116}