1use agcli::{
2 ActionParam, AgentCli, Command, CommandError, CommandOutput, NextAction,
3 truncate_lines_with_file,
4};
5use serde_json::json;
6
7fn main() {
8 let cli = AgentCli::new("ops", "Agent-native operations CLI")
9 .version(env!("CARGO_PKG_VERSION"))
10 .root_field("health", json!({ "server": "ok", "worker": "ok" }))
11 .command(
12 Command::new("status", "Show system health")
13 .usage("ops status")
14 .handler(|_req, _ctx| {
15 Ok(CommandOutput::new(json!({
16 "healthy": true,
17 "queue_depth": 0
18 }))
19 .next_action(NextAction::new("ops status", "Re-check status"))
20 .next_action(
21 NextAction::new("ops logs <source> [--lines <lines>]", "Inspect logs")
22 .with_param(
23 "source",
24 ActionParam::new()
25 .enum_values(["worker", "errors", "server"])
26 .default("worker"),
27 )
28 .with_param(
29 "lines",
30 ActionParam::new()
31 .description("Number of lines to show")
32 .default(20),
33 ),
34 ))
35 }),
36 )
37 .command(
38 Command::new("logs", "View logs with context-safe truncation")
39 .usage("ops logs <source> [--lines <lines>] [--follow]")
40 .handler(|req, _ctx| {
41 let source = req.arg(0).unwrap_or("worker");
42 let lines = req
43 .flag("lines")
44 .and_then(|value| value.parse::<usize>().ok())
45 .unwrap_or(20);
46
47 let fake_logs = (0..120)
48 .map(|idx| format!("[{source}] line-{idx}"))
49 .collect::<Vec<_>>();
50 let payload =
51 truncate_lines_with_file(fake_logs, lines, "ops-logs").map_err(|_| {
52 CommandError::new(
53 "failed to write full log output",
54 "LOG_WRITE_FAILED",
55 "Check disk permissions and retry.",
56 )
57 })?;
58
59 Ok(
60 CommandOutput::new(json!(payload)).next_action(NextAction::new(
61 "ops logs <source> [--lines <lines>] [--follow]",
62 "Adjust line count or follow logs",
63 )),
64 )
65 }),
66 );
67
68 let run = cli.run_env();
69 println!("{}", run.to_json());
70 std::process::exit(run.exit_code());
71}