1use crate::activity::ActivityStateValue;
2
3use clap::{Args, Command, CommandFactory, Parser, Subcommand};
4
5#[derive(Debug, Parser)]
6#[command(
7 name = "agent-id",
8 version,
9 about = "Portable identity registry for coding-agent sessions",
10 long_about = "agent-id assigns permanent human-readable names to stable agent-harness session IDs."
11)]
12pub struct Cli {
13 #[command(subcommand)]
14 pub command: Commands,
15}
16
17#[derive(Debug, Subcommand)]
18pub enum Commands {
19 Register(RegisterArgs),
21 Lookup(LookupArgs),
23 Annotate(AnnotateArgs),
25 Discover(DiscoverArgs),
27 Prune(PruneArgs),
29 Prime(PrimeArgs),
31}
32
33#[derive(Debug, Args)]
34pub struct RegisterArgs {
35 #[arg(value_name = "SESSION_ID", conflicts_with = "session_id")]
37 pub session: Option<String>,
38
39 #[arg(long = "session-id", value_name = "ID")]
41 pub session_id: Option<String>,
42
43 #[arg(long, value_name = "NAME")]
45 pub family: Option<String>,
46
47 #[arg(long, value_name = "NAME")]
49 pub realm: Option<String>,
50
51 #[arg(long)]
53 pub json: bool,
54}
55
56impl RegisterArgs {
57 pub fn explicit_session(&self) -> Option<&str> {
58 self.session.as_deref().or(self.session_id.as_deref())
59 }
60}
61
62#[derive(Debug, Args)]
63pub struct LookupArgs {
64 #[arg(value_name = "IDENTIFIER", conflicts_with = "session_id")]
66 pub input: Option<String>,
67
68 #[arg(long = "session-id", value_name = "ID")]
70 pub session_id: Option<String>,
71
72 #[arg(long)]
74 pub json: bool,
75}
76
77impl LookupArgs {
78 pub fn explicit_input(&self) -> Option<&str> {
79 self.input.as_deref().or(self.session_id.as_deref())
80 }
81}
82
83#[derive(Debug, Args)]
84pub struct AnnotateArgs {
85 #[arg(value_name = "SESSION_ID", conflicts_with = "session_id")]
87 pub session: Option<String>,
88
89 #[arg(long = "session-id", value_name = "ID")]
91 pub session_id: Option<String>,
92
93 #[arg(long, value_name = "TEXT", conflicts_with = "clear_summary")]
95 pub summary: Option<String>,
96
97 #[arg(long, conflicts_with = "summary")]
99 pub clear_summary: bool,
100
101 #[arg(long, value_name = "VALUE", conflicts_with = "clear_state")]
103 pub state: Option<ActivityStateValue>,
104
105 #[arg(long, conflicts_with = "state")]
107 pub clear_state: bool,
108
109 #[arg(long, value_name = "PATH", conflicts_with = "clear_cwd")]
111 pub cwd: Option<String>,
112
113 #[arg(long, conflicts_with = "cwd")]
115 pub clear_cwd: bool,
116
117 #[arg(long)]
119 pub json: bool,
120}
121
122impl AnnotateArgs {
123 pub fn explicit_session(&self) -> Option<&str> {
124 self.session.as_deref().or(self.session_id.as_deref())
125 }
126}
127
128#[derive(Debug, Args)]
129pub struct DiscoverArgs {
130 #[arg(long, default_value_t = 20)]
132 pub limit: usize,
133
134 #[arg(long, value_name = "HOURS")]
136 pub recent: Option<i64>,
137
138 #[arg(long, value_name = "NAME")]
140 pub realm: Option<String>,
141
142 #[arg(long)]
144 pub json: bool,
145}
146
147#[derive(Debug, Args)]
148pub struct PruneArgs {
149 #[arg(long, value_name = "TIMESTAMP", required = true)]
151 pub before: String,
152
153 #[arg(long)]
155 pub dry_run: bool,
156
157 #[arg(long)]
159 pub json: bool,
160}
161
162#[derive(Debug, Args)]
163#[command(about = "Output the agent-facing identity workflow manual")]
164pub struct PrimeArgs {
165 #[arg(long)]
167 pub prelude: bool,
168
169 #[arg(long)]
171 pub json: bool,
172}
173
174pub fn build_cli() -> Command {
175 Cli::command()
176}