1pub const FILTER_FORMATS: &str = "\
4Accepted filter formats:
5 --since/--until: YYYY-MM-DD, RFC3339, or a relative span like 7d, 12h, 2w, 30m
6 --provider: claude, codex, copilot, copilot-vscode, pi, openclaw (repeat the flag or comma-separate values)
7 --model: substring match, for example opus or gpt-5";
8
9pub const SESSIONS_EXAMPLES: &str = "\
10Examples:
11 claudex sessions --since 7d
12 claudex sessions --provider claude,codex --limit 10
13 claudex sessions --project claudex --file src/main.rs";
14
15pub const COST_EXAMPLES: &str = "\
16Examples:
17 claudex cost --since 30d
18 claudex cost --per-session --provider codex --model gpt-5
19 claudex cost --provider copilot --since 30d
20 claudex cost --project claudex --json";
21
22pub const SEARCH_EXAMPLES: &str = "\
23Examples:
24 claudex search \"panic\" --since 7d
25 claudex search \"release please\" --provider claude --case-sensitive
26 claudex search \"migration\" --role assistant --tool Bash --context 1
27 claudex search \"todo\" --project claudex --file src/ --json";
28
29pub const TOOLS_EXAMPLES: &str = "\
30Examples:
31 claudex tools --since 2w
32 claudex tools --per-session --provider claude
33 claudex tools --model opus --limit 15";
34
35pub const WATCH_HELP: &str = "\
36By default watches ~/.claudex/debug/latest.log. Claude Code does not
37write to that path on its own. Point Claude Code there per invocation:
38
39 claude --debug-file ~/.claudex/debug/latest.log
40
41Each new `claude` invocation truncates the file; watch detects this
42and prints a new-session separator. The directory is created on first
43run, so you can start `claudex watch` before launching claude.
44
45Examples:
46 claudex watch
47 claudex watch --follow /tmp/my-claude.log
48 claudex watch --raw";
49
50pub const SUMMARY_EXAMPLES: &str = "\
51Accepted values:
52 --plan api
53 --plan flat-monthly:USD, for example flat-monthly:250
54
55Examples:
56 claudex summary
57 claudex summary --provider openclaw --json
58 claudex summary --plan flat-monthly:250
59 claudex summary --json";
60
61pub const SESSION_EXAMPLES: &str = "\
62Examples:
63 claudex session abc12345
64 claudex session claudex --project utensils
65 claudex session abc12345 --json";
66
67pub const EXPORT_EXAMPLES: &str = "\
68Accepted values:
69 --format markdown
70 --format json
71
72Examples:
73 claudex export abc12345
74 claudex export claudex --format json --output session.json
75 claudex export abc12345 --project utensils";
76
77pub const INDEX_EXAMPLES: &str = "\
78Examples:
79 claudex index
80 claudex index --status
81 claudex index --prune-retained-days 180 --vacuum
82 claudex index --force";
83
84pub const PROVIDERS_EXAMPLES: &str = "\
85Examples:
86 claudex providers
87 claudex providers --json
88 claudex providers --deep
89 claudex providers --provider codex,openclaw";
90
91pub const TIMELINE_EXAMPLES: &str = "\
92Examples:
93 claudex timeline --since 30d
94 claudex timeline --weekly --limit 12
95 claudex timeline --provider codex --json";
96
97pub const BUDGET_EXAMPLES: &str = "\
98Examples:
99 claudex budget --monthly 250
100 claudex budget --monthly 50 --provider codex --json
101 claudex budget --monthly 250 --since 30d";
102
103pub const ACTIVITY_EXAMPLES: &str = "\
104Examples:
105 claudex activity --since 24h
106 claudex activity --limit 10
107 claudex activity --provider claude,codex --json";
108
109pub const TURNS_EXAMPLES: &str = "\
110Examples:
111 claudex turns --since 7d
112 claudex turns --provider claude --limit 10
113 claudex turns --project claudex --json";
114
115pub const PRS_EXAMPLES: &str = "\
116Examples:
117 claudex prs --since 30d
118 claudex prs --project claudex
119 claudex prs --provider claude --json";
120
121pub const FILES_EXAMPLES: &str = "\
122Examples:
123 claudex files --since 14d
124 claudex files --path src/ --project claudex
125 claudex files --provider claude,codex --json";
126
127pub const MODELS_EXAMPLES: &str = "\
128Examples:
129 claudex models --since 7d
130 claudex models --provider claude,codex
131 claudex models --model opus --json";
132
133pub const UPDATE_HELP: &str = "\
134Upgrade claudex in place when installed by install.sh. For other install
135sources the command prints the right upgrade recipe and exits:
136
137 Nix: nix profile upgrade claudex (or flake update)
138 cargo: cargo install claudex-cli --version X.Y.Z --force
139 Homebrew: brew upgrade claudex
140 pacman (AUR): paru -Syu claudex-bin (or yay / vanilla pacman)
141
142The latest tag is resolved by following the /releases/latest redirect, so
143this command does not hit api.github.com and cannot be rate-limited.
144
145Examples:
146 claudex update --check
147 claudex update
148 claudex update --version v0.2.0 --force";
149
150pub const COMPLETIONS_HELP: &str = "\
151Accepted shells:
152 bash, zsh, fish, elvish, powershell
153
154Examples:
155 source <(claudex completions zsh)
156 claudex completions fish | source
157 claudex completions bash";
158
159pub const SKILLS_EXAMPLES: &str = "\
160Examples:
161 claudex skills generate
162 claudex skills install --global --target codex
163 claudex skills generate --target claude-code,agents-md --force";
164
165pub const SKILLS_GENERATE_EXAMPLES: &str = "\
166Accepted targets:
167 claude-code, codex, pi, openclaw, agents-md, plugin, all
168
169Examples:
170 claudex skills generate
171 claudex skills generate --target codex --dir .
172 claudex skills generate --target claude-code,agents-md --force";
173
174pub const SKILLS_INSTALL_EXAMPLES: &str = "\
175Accepted targets:
176 claude-code, codex, pi, openclaw, agents-md, plugin, all
177
178Examples:
179 claudex skills install
180 claudex skills install --global --target codex
181 claudex skills install --target claude-code --force";
182
183pub fn examples_for_bin(bin: &str) -> Option<&'static str> {
184 match bin.strip_prefix("claudex ").unwrap_or(bin) {
185 "sessions" => Some(SESSIONS_EXAMPLES),
186 "cost" => Some(COST_EXAMPLES),
187 "search" => Some(SEARCH_EXAMPLES),
188 "tools" => Some(TOOLS_EXAMPLES),
189 "watch" => Some(WATCH_HELP),
190 "summary" => Some(SUMMARY_EXAMPLES),
191 "session" => Some(SESSION_EXAMPLES),
192 "export" => Some(EXPORT_EXAMPLES),
193 "index" => Some(INDEX_EXAMPLES),
194 "providers" => Some(PROVIDERS_EXAMPLES),
195 "timeline" => Some(TIMELINE_EXAMPLES),
196 "budget" => Some(BUDGET_EXAMPLES),
197 "activity" => Some(ACTIVITY_EXAMPLES),
198 "turns" => Some(TURNS_EXAMPLES),
199 "prs" => Some(PRS_EXAMPLES),
200 "files" => Some(FILES_EXAMPLES),
201 "models" => Some(MODELS_EXAMPLES),
202 "update" => Some(UPDATE_HELP),
203 "completions" => Some(COMPLETIONS_HELP),
204 "skills" => Some(SKILLS_EXAMPLES),
205 "skills generate" => Some(SKILLS_GENERATE_EXAMPLES),
206 "skills install" => Some(SKILLS_INSTALL_EXAMPLES),
207 _ => None,
208 }
209}
210
211pub fn uses_shared_filters(bin: &str) -> bool {
212 matches!(
213 bin.strip_prefix("claudex ").unwrap_or(bin),
214 "sessions"
215 | "cost"
216 | "search"
217 | "tools"
218 | "turns"
219 | "prs"
220 | "files"
221 | "models"
222 | "providers"
223 | "timeline"
224 | "budget"
225 | "activity"
226 )
227}
228
229pub fn error_help_for(bin: &str) -> String {
230 let mut out = String::new();
231 if uses_shared_filters(bin) {
232 out.push_str("\n\n");
233 out.push_str(FILTER_FORMATS);
234 }
235 if let Some(examples) = examples_for_bin(bin) {
236 out.push_str("\n\n");
237 out.push_str(examples);
238 }
239 out
240}