Skip to main content

kura_cli/commands/
read.rs

1use clap::{Args, Subcommand};
2
3use crate::commands::agent;
4
5#[derive(Subcommand)]
6pub enum ReadCommands {
7    /// Deterministic startup read plan via /v1/agent/context/section-index
8    Startup(ReadStartupArgs),
9    /// Fetch exactly one context section by id via /v1/agent/context/section-fetch
10    Section(ReadSectionArgs),
11    /// Compatibility bundled context read via /v1/agent/context
12    #[command(hide = true)]
13    Bundle(ReadBundleArgs),
14}
15
16#[derive(Args)]
17pub struct ReadStartupArgs {
18    /// Max exercise_progression projections to include (default: 5)
19    #[arg(long)]
20    exercise_limit: Option<u32>,
21    /// Max strength_inference projections to include (default: 5)
22    #[arg(long)]
23    strength_limit: Option<u32>,
24    /// Max custom projections to include (default: 10)
25    #[arg(long)]
26    custom_limit: Option<u32>,
27    /// Optional task intent used for startup section derivation
28    #[arg(long)]
29    task_intent: Option<String>,
30    /// Include deployment-static system config in response payload (default: API default=true)
31    #[arg(long)]
32    include_system: Option<bool>,
33    /// Optional response token budget hint (min 400, max 12000)
34    #[arg(long)]
35    budget_tokens: Option<u32>,
36}
37
38#[derive(Args)]
39pub struct ReadSectionArgs {
40    /// Stable section id from read startup
41    #[arg(long)]
42    section: String,
43    /// Optional page size for paged sections (1..200)
44    #[arg(long)]
45    limit: Option<u32>,
46    /// Optional opaque cursor for paged sections
47    #[arg(long)]
48    cursor: Option<String>,
49    /// Optional comma-separated top-level fields to project
50    #[arg(long)]
51    fields: Option<String>,
52    /// Optional task intent for startup section derivation
53    #[arg(long)]
54    task_intent: Option<String>,
55}
56
57#[derive(Args)]
58pub struct ReadBundleArgs {
59    /// Max exercise_progression projections to include (default: 5)
60    #[arg(long)]
61    exercise_limit: Option<u32>,
62    /// Max strength_inference projections to include (default: 5)
63    #[arg(long)]
64    strength_limit: Option<u32>,
65    /// Max custom projections to include (default: 10)
66    #[arg(long)]
67    custom_limit: Option<u32>,
68    /// Optional task intent used for context ranking
69    #[arg(long)]
70    task_intent: Option<String>,
71    /// Include deployment-static system config in response payload (default: API default=true)
72    #[arg(long)]
73    include_system: Option<bool>,
74    /// Optional response token budget hint (min 400, max 12000)
75    #[arg(long)]
76    budget_tokens: Option<u32>,
77}
78
79pub async fn run(api_url: &str, token: Option<&str>, command: ReadCommands) -> i32 {
80    match command {
81        ReadCommands::Startup(args) => {
82            agent::section_index(
83                api_url,
84                token,
85                args.exercise_limit,
86                args.strength_limit,
87                args.custom_limit,
88                args.task_intent,
89                args.include_system,
90                args.budget_tokens,
91            )
92            .await
93        }
94        ReadCommands::Section(args) => {
95            agent::section_fetch(
96                api_url,
97                token,
98                args.section,
99                args.limit,
100                args.cursor,
101                args.fields,
102                args.task_intent,
103            )
104            .await
105        }
106        ReadCommands::Bundle(args) => {
107            agent::context(
108                api_url,
109                token,
110                args.exercise_limit,
111                args.strength_limit,
112                args.custom_limit,
113                args.task_intent,
114                args.include_system,
115                args.budget_tokens,
116            )
117            .await
118        }
119    }
120}