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